すべて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から行を取得する方法を知りません。
答え1
$> 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]+"
。
答え2
私はawk
長い行をレコードに解析するのに慣れています。
awk 'BEGIN{FS="=";RS=" "}/^foo=/{print $2}'
これにより、各「単語」は、その単語内の「=」で区切られたフィールドと共に別々のレコードに設定されます。左側が「foo」の場合、「=」の右側のみが出力されます。$1=="foo"
「=」がない場合、最初のフィールドはレコード全体と同じであるため、代わりに正規表現を使用する必要があります。
答え3
シェル構成のみを使用してこれを実行できます。データを変数として読み取り、$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 …