쉘 스크립트의 패턴 일치 예외

쉘 스크립트의 패턴 일치 예외

따라서 특정 TV 시리즈의 에피소드 이름을 일괄적으로 바꾸는 다음 쉘 스크립트가 있습니다.

#!/bin/bash
#script for renaming files of form "*01*.ext" to "Episode 01.ext";
counter=0
for all_files in * ; do
  counter=$(( $counter+1  )) #increments $counter by 1;
  #creates counter "number" with two digit format (eg: 01):
  if [[ 1 = $(( $counter<10 )) ]] ; then
    number=0$counter
  else
    number=$counter
  fi
  #checks all file names for presence of $number and renames those files:
  for numbered_file in *$number* ; do 
    ext=${numbered_file##*.}
    mv "$numbered_file" "Episode $number.$ext"
  done
done

이제 몇 가지 매우 일반적인 예외를 해결하기 위해 스크립트를 개선하고 싶습니다. 특히 '720p'의 '20'이 '에피소드 20'을 가리키는 것으로 해석되는 것을 원하지 않습니다. 그래서 제가 원하는 것은 *$number*for 루프 내부에서 패턴을 다듬는 방법입니다. (변수 등에 할당됨 number)010203

다음을 달성하려면 어떻게 해야 합니까?

*여기에는 "7"이 없습니다. 여기에는 $number"0"이나 "p"가 없습니다 .*

위 스크립트에서 어색하게 수행되는 다른 사항을 자유롭게 지적해 주세요. 이것은 막연하게 유용한 스크립트에 대한 나의 첫 번째 시도이므로 아마도 문체적인 괴물로 가득 차 있을 것입니다. ;-)

답변1

예를 들어, 기존 도구를 재창조하려는 것 같습니다 mmv. rename이 도구라는 프로그램이 몇 개 있지만 rename제가 고려 중인 프로그램은 perl rename 일명입니다 prename(이것은 perl데비안과 파생 제품의 패키지에 포함되어 있으며 아마도 다른 패키지에도 포함되어 있을 것입니다). 배포판).

나는 그 사용법에 대한 몇 가지 예를 제공했지만 소스 파일 이름의 예는 제공하지 않았습니다(위 설명 참조).


그런데 스크립트가 sh가 아닌 bash이므로 if/then/else를 printf다음과 같이 bash에 내장된 제로 패딩 $number로 바꿀 수 있습니다.

printf -v number "%02d" "$counter"

POSIX 쉘에서는 number=$(printf "%02d" $counter)대신 사용할 수 있습니다. 이 printf명령은 GNU Coreutils의 일부입니다.

답변2

Bash에는 정규식 일치 구문이 있습니다.

[[ $string =~ regexp ]]

하지만 이것은 당신이 하고 싶은 일에 별로 도움이 되지 않습니다. 파일 이름에서 흥미로운 숫자를 추출하려면 지루한 부분을 제거하고 지루하지 않은 숫자의 마지막 시퀀스를 유지하십시오.

shopt -s extglob
number=$filename
number=${number//[0-9][0-9]+([0-9])p}
number=${number%%+([^0-9])}
number=${number##*[^0-9]}

관련 정보