Grep RegEx からグループをキャプチャする 質問する

Grep RegEx からグループをキャプチャする 質問する

shファイルの配列を調べるために、次のスクリプトを (macOS 10.6) に用意しました。

files="*.jpg"
for f in $files
    do
        echo $f | grep -oEi '[0-9]+_([a-z]+)_[0-9a-z]*'
        name=$?
        echo $name
    done

これまでのところ、ファイル名が指定された内容と一致している$nameかどうかに応じて、0、1、または 2 が保持されるだけですgrep。私が望むのは、括弧内の内容をキャプチャして([a-z]+)、それを変数に格納することです。

grep可能であれば、onlyを使いたいと思います。そうでない場合は、Python や Perl など、sedまたはそれに類するものは使用しないでください。私は、この問題を *nix 純粋主義者の観点から取り組みたいと思います。

ベストアンサー1

Bash を使用している場合は、以下を使用する必要さえありませんgrep

files="*.jpg"
regex="[0-9]+_([a-z]+)_[0-9a-z]*" # put the regex in a variable because some patterns won't work if included literally
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 の正規表現一致演算子である which を使用します。一致の結果は、と呼ばれる配列に保存されます$BASH_REMATCH。最初のキャプチャ グループはインデックス 1 に保存され、2 番目 (ある場合) はインデックス 2 に保存されます。以下同様です。インデックス 0 は完全一致です。




正規表現アンカーに関する補足事項 #1:

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 番目の例もこの一致に失敗することに注意してください。

grep演算子に関する補足事項 #2 \K:

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)演算子を使用します。この演算子は、その後に続くパターンに影響するため、その位置は重要です。

ファイル名に他の文字が含まれているかどうかに応じて、正規表現を調整する必要があるかもしれません。この場合、部分文字列がキャプチャされると同時に文字列を連結する例を示しています。

おすすめ記事