name=$(echo "$FILENAME" | grep -E '*\.(eng|por|pt-BR)\.*')
이 줄은 왜 작동하지 않나요?
만약 내가한다면
echo "Test (2013).1080p.por.mkv" | grep -E "*\.(eng|por)\.*"
작동합니다. "" 없이 ""를 사용하고 스크립트에서 '를 사용해 보았지만 grep으로 파이프되지 않은 것 같습니다. 왜인지 모르겠습니다. bash를 사용하고 있습니다.
FILENAME="Test (2013).1080p.por.mkv"
난 그냥 .por을 가져오고 싶어요. 또는 파일의 .eng
답변1
grep
패턴과 일치하는 (전체) 라인을 인쇄하는 도구입니다. 문자열의 일부를 추출하는 것은 적절하지 않습니다(일부 grep
구현 에서는 경우에 따라 이 옵션을 사용 -o<n>
하거나 사용할 수 있음).-o
여기에서 다음을 사용할 수 있습니다 expr
.
name=$(expr " $FILENAME" : '.*\.\(eng\)\.' '|' \
" $FILENAME" : '.*\.\(por\)\.' '|' \
" $FILENAME" : '.*\.\(pt-PT\)\.')
( 의 경우 foo.por.eng.bar
가 보다 우선합니다 eng
.)por
pt-PT
일부 expr
구현(예: GNU)은 expr
다음도 지원합니다.
name=$(expr " $FILENAME" : '.*\.\(eng\|por\|pt-PT\)\.')
(파일 이름이 두 개 이상인 경우 가장 오른쪽에 일치하는 항목이 반환됩니다.)
GNU grep
또는 호환 제품을 사용하세요.
name=$(
printf '%s\n' "$FILENAME" |
grep -Po '\.\K(eng|por|pt-PT)(?=\.)' |
head -n 1
)
(첫 번째 항목을 반환하고 마지막 항목 head
으로 대체)tail
case
또는 명령을 실행하지 않고 쉘 구성을 사용할 수 있습니다 .
case $FILENAME in
(*.por.*) name=por;;
(*.eng.*) name=eng;;
(*.pt-PT.*) name=pt-PT;;
esac
그리고 bash
:
re='\.(por|eng|pt-PT)\.'
[[ $FILENAME =~ $re ]]
name=${BASH_REMATCH[1]}
(첫 번째 발생. , 로 대체 zsh
)BASH_REMATCH
match
답변2
파일 이름이 다음과 같고 Some name.por.mkv
최종 확장자가 고정되어 있다고 가정하면 POSIX 쉘 문자열 조작을 사용할 수도 있습니다.
$ echo "$FILENAME"
Test (2013).1080p.por.mkv
$ x=${FILENAME%.mkv}; echo "${x##*.}"
por
여기에서 ${var%.mkv}
후행을 제거 .mkv
하고 ${var##*.}
(현재) 마지막 지점까지 모든 것을 삭제합니다. .mkv
첫 번째 확장으로만 변경하여 다른 확장을 처리 할 수 있습니다 .*
.