Bash의 문자열 클리핑

Bash의 문자열 클리핑

아래와 같이 변수에 문자열이 있다고 가정해 보겠습니다.

var="/fnxn/ngfdg/abc.ext"

다음과 같이 이 변수의 루트(확장자 .* 제거)를 얻을 수 있습니다.

echo ${var%.*}

다음과 같이 이 변수의 꼬리(경로 제거 */)를 얻을 수 있습니다.

echo ${var##*/}

하지만 이제 경로와 확장자를 제거해야 합니다. 아래와 같이 다른 변수를 사용하여 두 단계로 수행할 수 있습니다.

var2=${var##*/}
var3=${var2%.*}

그러나 단일 단계 옵션(아래 zsh 구문과 유사)은 bash에서 "Bad Substitution" 오류 메시지를 표시합니다.

echo ${${var##*/}%.*}

코드 길이를 줄이고 추가 환경 변수를 방지하기 위한 이해 가능한 단일 단계 옵션이 있으면 유용할 것입니다.

답변1

고정된 확장자가 있는 경우POSIXbasename시도 중인 자르기가 완벽하게 지원됩니다.

basename "$var" .ext

이렇게 하지 않으면zsh 확장당신이 시도하는 것에 대한 전폭적인 지원:

위의 name 대신 ${...} 유형의 매개변수 표현식이나 $(...) 유형의 명령 대체를 사용하는 경우 먼저 확장된 후 그 결과가 name의 값인 것처럼 사용됩니다. 따라서 중첩된 작업을 수행하는 것이 가능합니다. ${${foo#head}%tail}은 $foo 값을 삭제된 'head' 및 'tail'로 바꿉니다.

그래서 zsh에서

echo ${${var##*/}%.*}

당신이 기대하는 것을 할 것입니다.


Bash에서 작업 중이고 줄을 저장하려면 sed를 사용할 수 있습니다.

sed -e 's/\.[^.]*$//' <<<"${var##*/}"

.이는 접두사를 잃은 후와 마찬가지로 마지막 항목 이후의 모든 항목을 regex로 대체합니다 . 그러나 나는 이것이 두 줄 버전보다 특별히 메모리 효율적이라고 생각하지 않으며 아마 이해하기도 쉽지 않을 것입니다.

전체적으로 동일한 변수를 사용할 수 없는 이유는 없습니다.

var2=${var##*/}
var2=${var2%.*}

할당 전에 확장이 이루어지므로 안전합니다. 매우 긴 파일 이름이 두 번 저장되는 것이 문제라면 지금은 그런 일이 발생하지 않겠지만 현실적인 문제는 아니라고 생각합니다.

관련 정보