여러 개의 가능한 접미사 제거

여러 개의 가능한 접미사 제거

예: 이미지를 축소하는 빠른 명령을 만들고 싶습니다(내 파일 브라우저용).

...
FN="/tmp/some-image.jpg"
gm convert "$FN" -resize 50% "$(dirname $FN)/$(basename $FN .jpg/png/gif).jpg"
...

여러 접미사를 제거하도록 지정하려면 어떻게 해야 합니까?

답변1

basename접미사를 제거하고 어쨌든 원하지 않는 기본 이름을 제공하므로(디렉토리 구성 요소 제거) basename실제로는 사용자의 요구에 맞는 도구가 아닙니다.

문자열에서 데이터를 추출하는 기존 도구는 다음과 같습니다 expr.

FN_without_extension=$(expr "x$FN" : 'x\(.*\)\.')

그러나 최신 셸(예: zsh, bash, ksh, ash, yash모두 POSIX 호환 sh...)에는 연산자가 내장되어 있으므로 요즘에는 거의 필요하지 않습니다 expr(몇 가지 문제가 있으므로 피하는 것이 좋습니다).

${var%pattern}

끝에서 (가장 작은) 부분 일치 패턴을 제거합니다.$var

gm convert "$FN" -resize 50% "${FN%.*}.jpg"

쉘은 확장을 제거하기 위해 OR 연산자 tcsh를 선호합니다 zsh. 지쉬어:

gm convert $FN -resize 50% $FN:r.jpg

( r을 위한루트 이름).

확장자가 jpg/png/gif 중 하나인 경우에만 확장자를 제거하려면 상황이 더 복잡해지고 쉘에 따라 달라집니다.

그리고 zsh:

gm convert $FN -resize 50% ${FN%.(jpg|png|gif)}.jpg

그리고 ksh:

gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"

그리고 bash:

shopt -s extglob
gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"

그리고 expr:

gm convert "$FN" -resize 50% "$(
  expr \( "x$FN" : '\(.*\)\.png$' \| \
          "x$FN" : '\(.*\)\.jpg$' \| \
          "x$FN" : '\(.*\)\.gif$' \| "x$FN" \) : 'x\(.*\)')".jpg

(예, 복잡합니다. 이는 일부 문제를 해결하기 위한 것입니다 expr.)

일부 expr구현을 통해 다음과 같이 단순화할 수 있습니다.

expr \( "x$FN" : '\(.*\)\.\(png\|jpg\|gif\)$' \| "x$FN" \) : 'x\(.*\)'

다음을 사용할 수도 있습니다 sed.

FN_without_ext=$(printf '%s\n' "$FN" |
  sed -e '$!b' -e 's/\.png$//;t' -e 's/\.gif$//;t' -e 's/\.jpg$//')

대소문자를 구분하지 않으려면 png/gif/jpg위의 모든 솔루션을 로 바꿀 수 있습니다 [pP][nN][gG].... 일부 쉘/도구는 대소문자를 구분하지 않는 일치도 수행할 수 있습니다.

zsh:

 setopt extendedglob
 FN_without_ext=${FN%.(#i)(gif|png|jpg)}

ksh93:

 FN_without_ext=${FN%.~(i:gif|png|jpg)}

bash:

 shopt -s nocasematch
 LC_ALL=C
 if [[ $FN =~ (.*)\.(gif|png|jpg)$ ]]; then
   FN_without_ext=${BASH_REMATCH[1]}
 else
   FN_without_ext=$FN
 fi

그누 sed:

 FN_without_ext=$(printf '%s\n' "$FN" | sed -r '$s/\.(png|gif|jpg)$//I')

답변2

이것이 문제를 해결해야 합니까? 기본적으로 다음을 제거 .mp3하거나 .wav확장합니다.

$ basename -s .wav $(basename -s .mp3 'some_file.mp3')
some_file
$ basename -s .wav $(basename -s .mp3 'some_file.wav')
some_file
$ basename -s .wav $(basename -s .mp3 'some_file.rs') 
some_file.rs

관련 정보