Bash 스크립트 매개변수 정규식 그룹 충돌

Bash 스크립트 매개변수 정규식 그룹 충돌

간단한 bash 스크립트가 있습니다.


input_dir="`dirname $1`/`basename $1`/"
output_dir="`dirname $2`/`basename $2`/"
ext=$3
...
...
...
echo -n `rename "-f" "'s/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/'" "$output_dir"*.$ext`

$N문제는 일치 그룹이 스크립트의 명령줄 인수와 충돌하기 때문에 작동하지 않는다는 것입니다 . 이 문제를 어떻게 해결할 수 있나요?

답변1

귀하의 질문과 관련하여 대체가 발생하지 않도록 리터럴 문자열 주위에 작은 따옴표를 사용하십시오. 이 문자열에 작은따옴표를 사용해야 하는 경우 로 입력하세요 '\''.

echo -n `rename "-f" 's/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/' "$output_dir"*.$ext`

코드에 다른 문제가 있습니다. 변수 대체(예: $1및 ) $2또는 명령 대체(예: ) 의 결과는 `rename …`결과에 대해 토큰화 및 와일드카드 지정을 수행하는 셸에 의해 구문 분석됩니다.변수 대체 및 명령 대체에는 항상 큰따옴표를 사용하십시오.모르면 무시해야 합니다. 또한 백틱은 쉘에 의존하는 까다로운 방식으로 중첩된 따옴표를 처리하므로 사용하지 마십시오. 박물관을 제외한 모든 쉘은 더 건전한 $(…)구문을 지원합니다. 또한 a를 호출할 때 a를 사용해야 하며 --, a로 시작하는 경우에는 옵션처럼 보입니다.dirnamebasename$1$2-

input_dir="$(dirname -- "$1")/$(basename -- "$1")/"
output_dir="$(dirname -- "$2")/$(basename -- "$2"/)"
ext="$3"    # here it would be ok to omit the quotes, but if you're unsure of the rules, put the quotes in
echo -n "$(rename -f 's/.*([0-9]{11}_[0-9]{11}).*\.(.*)$/$1.$2/' "$output_dir"*".$ext")"

그런데, 여기서 달성하려는 것이 무엇인지 이해가 되지 않습니다. 호출하는 방식은 rename출력을 생성하지 않습니다.

답변2

일반적으로 쉘이 해석하는 것을 방지할 수 있습니다.메타 문자 백슬래시( )를 사용하여 \이스케이프 처리합니다 . 그래야 예방할 수 있어요모두$인수의 the는 rename앞에 백슬래시를 추가하여 확장됩니다.

echo -n `rename "-f" "'s/.*([0-9]{11}_[0-9]{11}).*\.(.*\$)/\$1.\$2/'" "$output_dir"*.$ext`

이 특별한 경우 문자열에는 s/.*([0-9]...$2/쉘 수준 대체가 필요하지 않으므로(질문의 요점은 이를 방지하는 방법입니다) '모든 쉘 처리를 차단하는 작은따옴표( )로 묶을 수 있습니다.

echo -n `rename "-f" 's/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/' "$output_dir"*.$ext`

-f( 쉘 메타 문자가 포함되어 있지 않으므로 인용할 필요가 없습니다 .)

관련 정보