현재 공백과 특정 이름을 제거하여 파일 이름을 바꾸는 스크립트가 있습니다. 지금까지 약 200개의 이름이 있으므로 제외할 이름의 배열이 더 나은 선택이 될 것이라고 생각했습니다.
prename -v 's/ /_/g' *
prename -v 's/_-_/_/g' *
prename -v 's/_\(Summer-HD\)//ig' *
prename -v 's/_\(Hammer\)//ig' *
prename -v 's/_\(Hardware-Hybrid\)//g' *
prename -v 's/_\(digital\)//ig' *
prename -v 's/_\(Resolution-SD\)//ig' *
지금까지 시도한 것은 제외하려는 이름을 반복하는 for 루프이지만 작동하지 않았습니다.
exclude=('(Summer-HD)' '(Hammer)' '(digital)' '(Resolution-SD)' '(Vacation)' '(Hammer-Hybrid)')
for x in "${exclude[@]}";
do prename -v 's/$x/_/g' * {} \;
done
이 for 루프는 전혀 작동하지 않고 깜박이는 커서만 남습니다. prename에 변수를 전달할 수 있는지 잘 모르겠습니다. 큰따옴표 사용에 대한 몇 가지 제안을 기반으로 for 루프를 일부 수정했습니다.
for x in "${exclude[@]}";
do prename -v 's/$x/_/g' *"$x"* {} \;
done
이것도 작동하지 않으며 이제 여기서 무슨 일이 일어나고 있는지 전혀 모릅니다. 현재 삭제하고 싶은 이름이 200개가 넘으므로 여전히 이름 배열을 원합니다. 이름에 관해서는 저는 그 생각에 동의하지 않습니다. sed 또는 awk가 도움이 될 수 있다고 들었습니다. 나는 그렇게 하고 싶지도 않습니다. 제공할 수 있는 아이디어나 도움에 감사드립니다.
답변1
스크립트 내에서 배열(또는 목록으로 구성된 정규식을 포함하는 스칼라 변수)을 정의할 수 있습니다 prename
. 사전 이름 스크립트 내에서 유효한 Perl 코드를 사용할 수 있다는 점을 기억하세요.예특수 Perl 스크립트). 예를 들어
$ touch foo_\(Summer-HD\)_\(digital\).mkv
$ prename -n 'BEGIN {
our $exclude=join("|", qw(Summer-HD Hammer digital Resolution-SD Vacation Hammer-Hybrid));
};
our $exclude;
s/_\((?:$exclude)\)//ig;' *
rename(foo_(Summer-HD)_(digital).mkv, foo.mkv)
여기에 주목할 만한 몇 가지 사항이 있습니다.
- 변수 범위 지정은 이름 바꾸기 스크립트에서 매우 중요하며
use strict
pragma가 적용됩니다. 시청하세요perldoc strict
(더 많은 내용이 있지만,간단히 말해서:strict
현재 범위에서 이전에 선언되지 않은 변수는 사용할 수 없습니다 . - 변수 는 파일 이름당 한 번이 아니라 스크립트가 실행될 때 한 번만 실행되도록
$exclude
블록에 정의됩니다 .BEGIN {}
여기에는 문자로 연결된 배열|
, 즉 정규식 대체가 포함됩니다. our
BEGIN 블록 외부에서 공유할 수 있도록 변수 로 정의됩니다 . 즉,File::Rename
패키지 범위 전체에서 사용할 수 있습니다. 이는 아마도 여러분이 알고 싶어하는 것 이상이므로 이름 바꾸기 스크립트의 전역 변수로 생각하면 됩니다. 메인 코드 블록도 이를 선언해야 합니다(만 사용됨our $exclude;
). 바라보다perldoc -f our
qw()
공백으로 구분된 단어 목록을 배열로 변환하는 Perl의 참조 연산자 중 하나입니다. 바라보다perldoc -f qw
. 그런데, Perl에서 "배열"과 "목록"은 거의 동의어입니다.perldoc -q difference.*list.*array
rename
여러 번 실행하기보다는 한 번 실행하려면 더 긴 스크립트(또는 여러 옵션)를 사용해야 한다는 점도 주목할 가치가 있습니다 -e '...script...'
. 예를 들어
$ prename -n 'BEGIN {
our $exclude=join("|", qw(Summer-HD Hammer digital Resolution-SD Vacation Hammer-Hybrid));
};
our $exclude;
s/ /_/g;
s/_-_/_/g;
s/_\((?:$exclude)\)//ig;' *
답변2
다음을 사용하는 것이 더 쉽습니다 zsh
.
exclude=(
'(Summer-HD)'
'(Hammer)'
'(digital)'
'(Resolution-SD)'
'(Vacation)'
'(Hammer-Hybrid)'
)
pattern="_(${(j[|])${(b@)exclude}})"
autoload -Uz zmv
zmv '*' '${f//$~pattern}'
이는 ${(b)exclude}
요소의 전역 연산자를 이스케이프 $exclude
하고 ${(j[|])...}
결과를 그것과 조인 하므로 결국 being (구체적으로: ) |
으로 끝나고 일괄 renamer 내부에서 ksh93의 연산자를 사용하여 일치 항목을 null로 바꿉니다 .$pattern
_(exclude1|exclude2...)
_(\(Summer-HD\)|\(Hammer\)|\(digital\)|\(Resolution-SD\)|\(Vacation\)|\(Hammer-Hybrid\))
${f//pattern[/replacement]}
zmv