printf에서 이름 바꾸기 명령을 사용하는 방법

printf에서 이름 바꾸기 명령을 사용하는 방법

TV 시리즈의 에피소드 수를 수정하려고 할 때 rename 함수를 사용해 보았고 printf의 반환 값을 rename 매개 변수로 전달하려고 시도했지만 실패했습니다. 거의 모든 조합을 시도해봤지만

for j in $(seq 1 9);
do 
    rename 's/"$( - "`printf "%d" ${j}`" - )"/"$( - "`printf "0%d" ${j}`" - )"/g' *
done

나는 생각할 수 있지만 아무것도 작동하지 않는 것 같습니다. 이 경우에는 1-9에만 관심이 있기 때문에 결국 수동으로 수행하게 되었습니다.

rename 's/- 1 -/- 01 -/g' *
rename 's/- 2 -/- 02 -/g' *
...

위의 내용이 나중에 참조할 수 없는 이유를 누군가가 지적할 수 있습니까?

답변1

전체 표현식을 작은따옴표로 인용하므로 쉘 보간이 발생하지 않습니다. Perl은 "$( - "printf "%d" ${j} 가장 이상한 정규 표현식을 보게 되며 " - )"이는 Perl에 의해 다음과 같이 보간됩니다.

% perl -E 'say qq{"$( - "`printf "%d" ${j}`" - )"}'
"42 640 - "`printf "%d" `" - )"
% 

$(Perl에게 변수 삽입을 요청했기 때문에 으로 변수를 읽을 수 있습니다 perldoc -v '$('. 이 정규식은 파일과 일치하지 않을 수 있습니다. (그리고 매우 복잡한 문자열에 여러 언어를 삽입하려고 할 때 발생하는 몇 가지 함정 중 하나를 보여줍니다. Perl이 모든 것을 할 수 있기 때문에 실제로 그럴 필요는 없습니다.)

더 나은 접근 방식은 관심 있는 항목을 일치시키고 조정하는 것입니다. 파일 이름에 숫자가 하나만 있다고 가정하면 하이픈으로 묶인 숫자인 것 같습니다. 역참조를 저장 ([0-9]+)하고 사용하세요.sprintf함수/e이 숫자를 적절하게 채웁니다( 오른쪽을 표현식으로 처리하여 실제로 호출되도록 하는 중요한 플래그도 추가 sprintf).

% touch "blah - "{1..9}" - blah"
% ls
blah - 1 - blah blah - 3 - blah blah - 5 - blah blah - 7 - blah blah - 9 - blah
blah - 2 - blah blah - 4 - blah blah - 6 - blah blah - 8 - blah
% rename 's/([0-9]+)/sprintf "%02d", $1/e' *
% ls
blah - 01 - blah    blah - 04 - blah    blah - 07 - blah
blah - 02 - blah    blah - 05 - blah    blah - 08 - blah
blah - 03 - blah    blah - 06 - blah    blah - 09 - blah
% 

파일 이름에 다른 곳에 숫자가 있으면 정규식을 사용하여 이를 설명하십시오. 아마도 다음과 같습니다.

% rename 's/- ([0-9]+) -/sprintf "- %d -", $1/e' *
% ls
blah - 1 - blah blah - 3 - blah blah - 5 - blah blah - 7 - blah blah - 9 - blah
blah - 2 - blah blah - 4 - blah blah - 6 - blah blah - 8 - blah
% 

rename정규식을 가장 효과적으로 사용 하려면 다음을 참조하세요.

관련 정보