bash - 모든 하위 디렉터리의 모든 mp3 파일에서 처음 3자와 마지막 1자를 제거합니다.

bash - 모든 하위 디렉터리의 모든 mp3 파일에서 처음 3자와 마지막 1자를 제거합니다.

기본 디렉터리에는 다음과 같은 폴더가 있습니다.

1
2
3
4
5
10
110

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

  0010011.mp3  0010031.mp3  0010051.mp3  0010071.mp3  0010021.mp3  0010041.mp3  0010061.mp3

그래서 처음 3자와 마지막 1자를 제거하여 파일이 다음과 같이 보이도록 하고 싶습니다.

 001.mp3   003.mp3   005.mp3   007.mp3   002.mp3   004.mp3  006.mp3

나는 이것을 시도했다

for file in ??????*; do echo mv $file `echo $file | cut -c4-`; done

이는 하위 디렉터리에서도 작동하지 않으며 기본 디렉터리에 있는 파일만 작동합니다.

답변1

단지 *.mp3와 일치하는 모든 파일을 수집한 다음 파일 이름을 자르는 것은 권장하지 않습니다. 나중에(예: 다음 주) 동일한 스크립트를 다시 실행하고 싶을 수 있으며 동일한 파일의 이름을 다시 바꾸려고 시도하여 파일이 더 짧아지고 이름 지정 충돌이 발생해서는 안 됩니다.

예제 파일 이름은 다음과 같습니다.001xyz1.mp3당신이 원하는xyz.mp3

     KEEP_DIR=$PWD 
     cd /your/music/base_dir        # sub-dirs holding .mp3

     RCOUNT=0 ; SKIP=0 ; FCC=0


 for FFF in */001???1.mp3    
     do
     LOC="$(dirname $FFF)"   
     BAS="$(basename $FFF)"
     TRIM1="${BAS#1.mp3}"     #could use ${BAS:4:3}
     NEWF="$LOC/${TRIM1%001}.mp3"
     if [ -e "$NEWF" ] ; then
        echo "#-- File $NEWF already exists, not renaming $FFF"
        SKIP=$((SKIP+1))
     else
        mv $FFF $NEWF
        MCOUNT=$((MCOUNT+1))
     fi
     FCC=$((FCC+1))
 done

 echo "Renamed $MCOUNT mp3 files, of $FCC found. (Skipped $SKIP)"
 cd $KEEP_DIR

 #--[eof]

답변2

rename(때때로 호출 되는) 경우 prename단일 명령으로 이 작업을 수행할 수 있습니다.

rename -n 's!(.*/)...(.*).(\.mp3)!$1$2$3!' */?????*.mp3

또는 파일을 반복할 수 있습니다.

for f in */?????*.mp3
do
    echo mv -v "$f" "$(echo "$f" | sed -r 's!(.*/)...(.*).(\.mp3)!\1\2\3!')"
done

첫 번째 경우에는 제거 -n(또는 으로 대체 -v)하여 작업을 수행합니다. 두 번째 인스턴스에서는 echo변경 사항을 적용할 수 있도록 첫 번째 인스턴스를 삭제합니다.

답변3

7자 길이의 기본 이름을 사용하여 각 mp3에 대한 sed명령줄을 만들 수 있습니다.mv

$ find . -name "???????.mp3" | sed 's/\(.*\)\(...\)\(...\)\(.\)\(\.mp3\)/mv \1\2\3\4\5 \1\3\5/'

출력을 본 후 파일로 리디렉션하여 실행할 수 있습니다.

관련 정보