grep
is the tool to print (whole) lines matching a pattern. It's not appropriate to extract parts of a string (though some grep
implementations have -o<n>
or -o
options that can be used in some cases for that).
Here, you can use expr
:
name=$(expr " $FILENAME" : '.*\.\(eng\)\.' '|' \
" $FILENAME" : '.*\.\(por\)\.' '|' \
" $FILENAME" : '.*\.\(pt-PT\)\.')
(for foo.por.eng.bar
, gives priority to eng
over por
over pt-PT
).
Some expr
implementations like GNU expr
also support:
name=$(expr " $FILENAME" : '.*\.\(eng\|por\|pt-PT\)\.')
(here returns the rightmost occurrence if there are several in the filename)
With GNU grep
or compatible:
name=$(
printf '%s\n' "$FILENAME" |
grep -Po '\.\K(eng|por|pt-PT)(?=\.)' |
head -n 1
)
(returns first occurrence, replace head
with tail
for last)
Or you could use your shell's case
construct and not run any command at all:
case $FILENAME in
(*.por.*) name=por;;
(*.eng.*) name=eng;;
(*.pt-PT.*) name=pt-PT;;
esac
With bash
:
re='\.(por|eng|pt-PT)\.'
[[ $FILENAME =~ $re ]]
name=${BASH_REMATCH[1]}
(first occurrence. With zsh
, replace BASH_REMATCH
with match
)
$name
empty? How do you check it? Do you get an error?, What do you get if you replacegrep -E ...
withsed -n l
? What do you expect to achieve with that command? What about doingcase $FILENAME in (*.eng.* | *.por.* | *.pt-BR.*) ...; esac
?$name
is empty and I set$FILENAME
before it withFILENAME="Test (2013) [HDTV-720p].bluray.1080p.por.mkv"