가변 길이 파일 이름 "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 명령을 포함하고 이름을 문자열로 묶는 것입니다.