[解決済み】Grep RegExからグループをキャプチャする
質問
私は、この小さなスクリプトを
sh
(Mac OSX 10.6) で、ファイルの配列に目を通すことができます。Googleはこの時点で役に立たなくなった。
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
のみ、可能であれば
. そうでない場合は、PythonやPerlなどはご遠慮ください。
sed
私はシェルの初心者なので、*nixの純粋主義者の角度からこれを攻撃したいと思います。
また
超カッコイイボヌ
シェルで文字列を連結する方法について教えてください。キャプチャしたグループが $name に格納されている "somename" という文字列で、その末尾に ".jpg" という文字列を追加したい場合、以下のようにすればよいでしょうか。
cat $name '.jpg'
?
お時間があれば、ご説明をお願いします。
解決方法は?
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}
).
は、その
(?=)
演算子は固定長または可変長のパターンにマッチし、"look-ahead" と呼ばれます。また、マッチした文字列は結果に含まれません。
大文字と小文字を区別しないマッチを行うために
(?i)
演算子が使用されます。これは、それに続くパターンに影響を与えるので、その位置は重要である。
ファイル名に他の文字が含まれているかどうかで、正規表現を調整する必要があるかもしれません。今回は、部分文字列を取り込むと同時に文字列を連結する例を示していることに注意してください。
関連
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] ファイルを grep して、その周辺の行をいくつか表示する?
-
[解決済み] scpを使ってリモートからローカルにフォルダをコピーするにはどうしたらいいですか?
-
[解決済み] Bashスクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] すべてのディレクトリとサブディレクトリを再帰的にgrepするにはどうしたらいいですか?
-
[解決済み] Gitの履歴からコミットしたコードをgrep(検索)する方法
-
[解決済み] Linux で grep を使ってファイル名だけを表示するにはどうしたらいいですか?
-
[解決済み] grepによるネガティブマッチング(fooを含まない行にマッチする)
-
[解決済み] 連続したストリームを「grep」する方法とは?
-
[解決済み】特定の拡張子を持つファイルのみを再帰的にgrepするにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】「ambiguous redirect」エラーが発生する
-
[解決済み】Bashのif条件で「unary operator expected」エラーが発生する。
-
[解決済み] Bashで$()と`の違いはあるのでしょうか?重複] [重複
-
[解決済み] OS X で 'find' コマンドを使用して 'sed' を使用するとエラーが発生する。"無効なコマンドコードです。"
-
[解決済み] Homebrewは最新ですが、`could not link` + `delete path` のエラーは気にしなくていいのでしょうか?
-
[解決済み] echoコマンドでパイピングが効かない [重複]。
-
[解決済み] bash スクリプトを実行しているドッカーエントリーポイントが "パーミッション拒否" になる
-
[解決済み] ファイル内の大文字・小文字を区別しない文字列を grep するには?
-
[解決済み] bashスクリプトでfindコマンドを使用する
-
[解決済み] sedでキャプチャしたグループのみを出力するには?