Grep は引用符があっても変数を使用しません。

Grep は引用符があっても変数を使用しません。

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。)porpt-PT

いくつかのexpr実装(例:GNU)はexpr以下もサポートしています。

name=$(expr " $FILENAME" : '.*\.\(eng\|por\|pt-PT\)\.')

(ファイル名が2つ以上の場合、一番右側に一致する項目が返されます。)

GNUgrepまたは互換製品を使用してください。

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]}

(最初の発生。、に置き換えますzshBASH_REMATCHmatch

答え2

ファイル名が次のようになり、最後のSome name.por.mkv拡張子が固定されていると仮定すると、POSIXシェル文字列操作を使用することもできます。

$ echo "$FILENAME"
Test (2013).1080p.por.mkv
$ x=${FILENAME%.mkv}; echo "${x##*.}"
por

ここから${var%.mkv}末尾を削除.mkvし、${var##*.}(現在)最後のポイントまですべてを削除します。.mkv最初の拡張にのみ変更して他の拡張を処理できます.*

関連情報