すべて1行の大きなテキストファイルがあります。本文には_foo=12345
_のようなセクションがいくつかあり、ファイルの残りの部分を無視して、それらすべてを別々の行として抽出する必要があります。
例えば:
_random junk foo=12345 more junk random junk foo=2345 junk foo=7654 junk random foo=5432 junk
_
私が抜け出したいのは:
_12345
2345
7654
5432
_
foo=([0-9]+)
を抽出するための正規表現の記述方法は知っていますが、それをテキストに適用して行をbashで出力する方法がわかりません。
_$> echo "random junk foo=12345 more junk random junk foo=2345 junk foo=7654 junk random foo=5432 junk" | grep --only-matching --Perl-regexp "(?<=foo=)[0-9]+"
12345
2345
7654
5432
_
ここで行ったことは、"(?<=foo=)[0-9]+"
でlookbehindregexを使用することです。
awk
を使用して、長い行をレコードに解析します。
awk 'BEGIN{FS="=";RS=" "}/^foo=/{print $2}'
これにより、各「Word」が個別のレコードとして設定され、そのWord内で「=」を使用してフィールドが個別に設定されます。次に、左側が「foo」の場合、「=」の右側を出力するだけです。 '='がない場合、最初のフィールドはレコード全体と同じであるため、$1=="foo"
の代わりに正規表現を使用する必要があります。
これは、シェル構造のみで行うことができます。データを変数に読み取り、この変数を$IFS
(デフォルトでは空白)の文字で分割し、必要なチャンクを保持します。二重引用符の外側の変数置換では、単語の分割(ここで必要)とファイル名の生成(別名、グロブ、不要)が行われるため、最初にset +f
でグロブをオフにします。
set +f
for x in $(cat /path/to/file); do
case "$x" in
foo=*) echo "${x#*=}";;
esac
done
set -f
cat
を呼び出す代わりに、read
ビルトインを使用できます。
set +f
read -r line </path/to/file
for x in $line; do …