bash는 파일 이름에서 첫 번째 숫자를 추출합니다.

bash는 파일 이름에서 첫 번째 숫자를 추출합니다.

다음과 같이 파일을 이동하려고 합니다.

...
DLG023-00-01-sprite.TextGrid.json
DLG023-00-01.prosody.json
DLG023-01-01-sprite.ogg
DLG023-00-02-sprite.TextGrid.json
DLG023-00-02.prosody.json
DLG023-01-02-sprite.ogg
...
DLG028-00-01-sprite.TextGrid.json
DLG028-00-01.prosody.json
DLG028-01-01-sprite.ogg
...

각각의 폴더에 넣습니다. 예: 파일이 ; dialogue023/로 시작하는 위치 로 이동합니다. ; 로 시작하는 DLG023경우 등등.dialogue024/DLG024

모든 파일과 디렉터리는 동일한 수준에 있습니다.

즉, 다음과 같은 명령을 생성하려고 합니다.

mv DLG023-00-01-sprite.ogg dialogue023/

파일 이름에서 첫 번째 숫자를 어떻게 추출합니까?

지금까지 나는 이것을 얻었습니다 :

for i in DLG*-*-*-sprite.ogg; do echo "${i//[^0-9]}";done

그러나 이것은 첫 번째 숫자(예: 23)만 원할 때 모든 숫자(예: 230001)를 출력합니다.

답변1

-t.NET에 옵션이 없는 OS X를 사용하고 있다고 가정합니다 mv. 스크립트가 수천 개의 파일을 처리하는 경우 속도가 매우 느려집니다.

    for file in DLG*; do
    # Extract the three digits after DLG
    getnum=${file%%-*}
    getnum=${getnum#???}

    # make the directory dialogue### or exit if there is an error
    echo mkdir -p "dialogue${getnum}" || exit

    echo mv "$file" "dialogue${getnum}"
    done

echo이전 mkdirmv출력이 만족스러운 경우를 제거합니다 .

답변2

다음을 사용하여 mv 명령을 생성할 수 있습니다.

for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done

이제 명령은 다음과 같이 인쇄됩니다.

mv "DLG023-00-01.prosody.json" "dialogue023/"
[...]
mv "DLG028-00-01.prosody.json" "dialogue028/"
[...]

원하는 것이면 해당 출력을 파이프로 연결하면 bash실행됩니다.

for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done | bash

답변3

다음을 사용하는 한 줄 솔루션 find:

find . -name DLG* -exec bash -c 'DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/"); mkdir "$DEST"; mv "$0" "$DEST"' {} \;
  • findDLG*이 디렉토리에서 파일을 찾는 명령입니다 .
  • 모든 결과에 대해 bash -c문장을 실행하십시오.

문장 에서 bash:

  • DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/");find( $0)에서 모든 결과를 선택하고 sed첫 번째 -(DLG([0-9]+)-.*) 앞의 모든 숫자를 dialogue해당 숫자( dialogue\1)로 바꾸고 이라는 변수에 입력합니다 DEST.
  • mkdir "$DEST"필요한 폴더를 만듭니다.
  • mv "$0" "$DEST"'파일을 해당 디렉토리로 이동합니다.

답변4

몇 가지 아이디어:

for i in DLG*-\*-\*-sprite.ogg; do echo "${i//[^0-9]}" | head -c 2; echo ;done

길이가 모두 같다고 확신하는 경우:

for i in DLG*-\*-\*-sprite.ogg; do echo "${i:3:3}" ;done

관련 정보