모든 파일에서 첫 번째 문자를 제거합니다("0"인 경우).

모든 파일에서 첫 번째 문자를 제거합니다("0"인 경우).

여러 폴더가 있습니다.

1
2
3
4
5

그래서 각 폴더에는 다음과 같은 파일이 있습니다.

00123.mp3
00133.mp3
00150.mp3

그래서 다 삭제하고 싶어요0파일 이름의 시작 부분에 있는 경우

나는 이것을 시도했다

for file in *; do echo mv "$file" "${file//[ ()@0]/}"; done

하지만 그것은 모두 제거0시작 부분과 파일 이름 내부(처음에 필요함)는 하위 디렉터리에서도 작동하지 않습니다.

답변1

Bash를 사용하는 경우 이 스크립트는 요청한 작업을 수행합니다.

#!/bin/bash
shopt -s extglob
while IFS= read -d '' f ; do
    file=${f##*/}
    dir="${f%/*}/"
    echo \
    mv "$dir$file" "$dir${file##+(0)}"
done < <(find . -type f -name '0*.mp3' -print0)

이동할 파일 목록에 동의하면 해당 echo \줄을 주석 처리하여 실제로 명령을 실행합니다.mv

또는 이식성을 위한 다음 sh 버전:

#!/bin/sh

find . -type f -name '0*.mp3' -print |
while IFS= read f; do
    file=${f##*/}
    dir="${f%/*}/"
    f2=$file; until [ "$f2" = "${f2#0}" ]; do f2=${f2#0}; done
    echo \
    mv "$f" "$dir${f2}"
done

답변2

rename귀하의 질문에 Linux 태그가 지정되었으므로 또는 명령을 사용할 수 있습니다 prename( prename 더 이상 사용되지는 않지만 여전히 작동합니다). 두 경우 모두 패턴 기반 이름 바꾸기를 위한 Perl 스크립트입니다.

그룹 일치를 수행하고 glob을 사용하여 파일 *.mp3만 전달하면 다음을 수행할 수 있습니다..mp3

$ prename  -nv 's/(^0*)(.*).mp3/$2.mp3/' *.mp3
Deprecated program in use: rename as shipped with the Debian perl package will be removed after the release of stretch. Please install the separate 'rename' package which will provide the same command.
000004500.mp3 renamed as 4500.mp3
00123.mp3 renamed as 123.mp3
00133.mp3 renamed as 133.mp3
00150.mp3 renamed as 150.mp3

-n및 는 시험 -v실행 및 자세한 테스트용으로만 사용됩니다. -n실제 이름 변경을 적용하려면 제거하세요 .

renamevs 에 대해 혼란스럽다면 다음 prename을 읽어보세요.해당 답변이렇게 하면 혼란이 사라집니다. 하지만... 귀찮게 하지 않는 것이 좋습니다. 너무 복잡합니다 :) 요점은 ksh쉘을 사용하지 않는 한 두 경우 모두 표시된 대로 작동한다는 것입니다.


하위 폴더의 파일 이름을 바꾸는 재귀적인 방법은 via 이지만 find, 제공된 대로 파일 경로의 이전 항목을 처리하려면 교체 패턴이 있는 일부 곡예가 필요합니다 find.

find ./testdir/ -type f -name "*.mp3" -exec  prename  -nv 's/(.*)(\/0*)(.*).mp3/$1\/$3.mp3/' {} \;

위 명령은 테스트 케이스에서 다음과 같이 실행됩니다.

$ find ./testdir/ -type f -name "*.mp3" -exec  prename  -nv 's/(.*)(\/0*)(.*).mp3/$1\/$3.mp3/' {} \;  2>/dev/null
./testdir/000004500.mp3 renamed as ./testdir/4500.mp3
./testdir/00150.mp3 renamed as ./testdir/150.mp3
./testdir/00133.mp3 renamed as ./testdir/133.mp3
./testdir/00123.mp3 renamed as ./testdir/123.mp3

\d숫자 카테고리를 지정하면 약간의 개선이 있을 수 있습니다 .

find ./testdir/ -type f -name "*.mp3" -exec  prename  -nv 's/\/0*(\d*\.mp3)/\/$1/' {} \;

Stéphane Chazelas는 댓글에서 /0/1.mp3실수로 이름이 변경될 가능성을 언급했습니다 .//1.mp3. 나는 여러 가지 테스트 케이스를 받아 결과를 얻었습니다 ./testdir/0/000987.mp3 renamed as ./testdir/0/987.mp3. 욕심 많은 매칭이 효과가 있을 것 ./testdir/007/00123.mp3 renamed as ./testdir/007/123.mp3같아요 . 0*그는 또한 [^/]댓글에 파일 이름 패턴 일치를 추가할 것을 제안했습니다. Unix 파일 이름에는 백슬래시를 사용할 수 없지만 개별 파일에는 사용할 수 없으므로 이는 좋은 생각입니다. 그러나 이를 더 잘 구현하는 방법을 잘 모르겠으며 파일 이름 일치 0.mp3000.mp3유형에 대한 제안도 아직 없습니다.

답변3

그리고 zsh:

autoload zmv # best in ~/.zshrc
zmv -n '0#(*.mp3)' '$1'

(만족하면 삭제하세요 -n(모의 실행)).

#in의 전역 연산자는 zsh정규식 *연산자와 유사합니다.

0000.mp3이름이 로 변경됩니다 .mp3. 이를 방지하려면 다음과 같이 변경할 수 있습니다.

zmv -n '0#([0-9]*.mp3)' '$1'

재귀적으로:

zmv -n '(**/)0#([0-9]*.mp3)' '$1$2'

예제에서 제안한 대로 문자를 제거하려면 () @다음을 수행해야 할 수도 있습니다.

zmv -n '(**/)0#([0-9]*.mp3)' '$1${2//[() @]}'

(단, 파일명에서 숫자로 시작하지 않는 문자는 제거되지 않습니다.)

관련 정보