Bashを使用している場合は、使用する必要もありませんgrep
。
files="*.jpg"
regex="[0-9]+_([a-z]+)_[0-9a-z]*"
for f in $files # unquoted in order to allow the glob to expand
do
if [[ $f =~ $regex ]]
then
name="${BASH_REMATCH[1]}"
echo "${name}.jpg" # concatenate strings
name="${name}.jpg" # same thing stored in a variable
else
echo "$f doesn't match" >&2 # this could get noisy if there are a lot of non-matching files
fi
done
正規表現を変数に入れることをお勧めします。一部のパターンは、文字どおりに含まれていると機能しません。
これ =~
は、Bashの正規表現一致演算子を使用します。一致の結果はという配列に保存され$BASH_REMATCH
ます。最初のキャプチャグループはインデックス1に格納され、2番目のキャプチャグループ(存在する場合)はインデックス2に格納されます。インデックス0は完全一致です。
アンカーがない場合、この正規表現(およびを使用するものgrep
)は、以下の例などと一致しますが、探しているものとは異なる場合があることに注意してください。
123_abc_d4e5
xyz123_abc_d4e5
123_abc_d4e5.xyz
xyz123_abc_d4e5.xyz
2番目と4番目の例を削除するには、次のように正規表現を作成します。
^[0-9]+_([a-z]+)_[0-9a-z]*
これは、文字列が1つ以上の数字で始まる必要があることを示しています。カラットは文字列の始まりを表します。次のように正規表現の最後にドル記号を追加すると、
^[0-9]+_([a-z]+)_[0-9a-z]*$
次に、ドットが正規表現の文字の中になく、ドル記号が文字列の終わりを表すため、3番目の例も削除されます。4番目の例もこの一致に失敗することに注意してください。
あなたがGNUを持っているならgrep
(約2.5以降、\K
演算子が追加されたときだと思います):
name=$(echo "$f" | grep -Po '(?i)[0-9]+_\K[a-z]+(?=_[0-9a-z]*)').jpg
\K
オペレータ(可変長ルックビハインド)は直前のパターンが一致させるが、結果に一致するものを含んでいません。同等の固定長は(?<=)
-パターンは右括弧の前に含まれます。あなたは使用する必要があります\K
数量が異なる長さの文字列を一致させる可能性がある場合(例えば+
、*
、{2,4}
)。
(?=)
オペレータは、固定または可変長のパターンと「先読み」と呼ばれていると一致します。また、一致した文字列は結果に含まれません。
大文字と小文字を区別せずに一致させるには、(?i)
演算子を使用します。それはそれに続くパターンに影響を与えるので、その位置は重要です。
ファイル名に他の文字があるかどうかに応じて、正規表現を調整する必要がある場合があります。この例では、部分文字列がキャプチャされると同時に文字列を連結する例を示しています。