Linux에서 파일 이름의 일부를 바꾸는 방법은 무엇입니까?

Linux에서 파일 이름의 일부를 바꾸는 방법은 무엇입니까?

가변 길이 파일 이름 "abcdef - ghijkl.pdf"를 가져와 "ghijkl - abcdef.pdf"로 이름을 바꿉니다.

단일 폴더에 있는 모든 파일에 대한 명령줄 스크립트에서 이를 어떻게 달성할 수 있습니까?

답변1

Ubuntu를 사용하고 있으므로 최소한 Perl 기반 rename또는prename

$ rename -n -- 's/(\w*) - (\w*)/$2 - $1/' *.pdf
rename(abcdef - ghijkl.pdf, ghijkl - abcdef.pdf)

$ prename -n -- 's/(\w*) - (\w*)/$2 - $1/' *.pdf
abcdef - ghijkl.pdf renamed as ghijkl - abcdef.pdf

또는 설치하여 사용할 수 있습니다.mmv

$ mmv -n '* - *.pdf' '#2 - #1.pdf'
abcdef - ghijkl.pdf -> ghijkl - abcdef.pdf

(모든 경우에 삭제는 -n실제로 작업을 완료하는 것입니다.)

답변2

배시 사용:

[[ $f =~ ^([^-]+)\ -\ ([^\.]+)\.(.*) ]] && 
  mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}.${BASH_REMATCH[3]}"

이것은 bash의 정규식 테스트 연산자를 사용하여 =~주어진 파일 이름( in )이 패턴과 일치하는지 확인합니다 $f. "대시를 제외한 모든 것, 공백 대시 공백, 마침표를 제외한 모든 것, 마침표, 그 뒤에 모든 것". 파일 이름이 패턴과 일치하면 정규식의 괄호로 묶인 하위 부분의 일치하는 비트가 BASH_REMATCH 배열의 요소에 할당됩니다.

특정 폴더의 모든 파일에 대해 이 작업을 수행하려면:

cd /to/that/folder
for f in *
do
  [ -f "$f" ] || continue
  [[ $f =~ ^([^-]+)\ -\ ([^\.]+)\.(.*) ]] && 
    mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}.${BASH_REMATCH[3]}"
done

만 사용POSIX 지정 변수 확장:

pre=${f%%.*}
ext=${f##*.}
mv "$f" "${pre##*- } - ${pre%% -*}.$ext"

답변3

다음 명령을 사용하여 스크립트를 만들 수 있습니다.

\ls *-*.pdf | sed 's/\(.*\)-\(.*\).pdf/mv \1-\2.pdf \2-\1.pdf/' > script_mv.bash

그런 다음 스크립트가 올바른지 확인하고 실행할 수 있습니다.

. ./script_mv.bash

나는 ls에 대한 옵션을 취소하기 때문에 \ls를 썼습니다.

sed 모드의 의미는 다음과 같습니다.

  • 1, "-", 2, ".pdf" 중 하나를 찾았습니다.
  • 두 내용 모두 ( )로 묶여서 \1과 \2라는 이름을 얻습니다.
  • 그런 다음 mv 행을 복사하고 \1과 \2로 인해 파일 이름을 다시 만들 수 있습니다.

답변4

"xxx-yyyy.ddd" 이름 패턴과 관련된 부끄러운 대답입니다.

find -type f | while read flnm ; do basename "$flnm" | awk -F'[\ .]' '{print $3 " " $2 " " $1 "."$4}'; done

파일을 찾아 while read 루프에 이름을 지정합니다. 거기에서 basename을 사용하여 이름을 추출하고 Awk에 제공합니다. awk는 여러 필드 구분 기호, 공백 및 마침표를 사용한 다음 원하는 순서로 필드를 다시 인쇄합니다.

abcdef - ghijkl.pdf

~이 되다

ghijkl - abcdef.pdf

실제 적용...파일 이름을 이 새 스키마 이름으로 바꿉니다.

find -type f | while read flnm ; do mv "$(basename "$flnm")"  "$(basename "$flnm" | awk -F'[\ .]' '{print $3 " " $2 " " $1 "."$4}')"; done

유일한 차이점은 mv 명령을 포함하고 이름을 문자열로 묶는 것입니다.

관련 정보