他のファイルのパターンと一致する場合にのみファイルの行を変更します。

他のファイルのパターンと一致する場合にのみファイルの行を変更します。

次の2つのファイルがあるとしましょう。

子供の鬼

11 hello
22 wonderful
33 beach
44 today
55 is
66 great

軽く叩く

11
44
55

私はinpで何かをしたいのですが、patsの行だけでやりたいです。たとえば、最後に+を追加したいと思います。最終結果は次のとおりです。

出る

11 hello+
22 wonderful
33 beach
44 today+
55 is+
66 great

sed、awkなどを使用してこれを行う簡単な方法はありますか?簡単に言えば、私は(例えばPython)プログラムを書くことを望まないgrep -f pats inp+と同じものを一緒に見つけることを好みますsed 's/$/+/'

編集する:

たとえば、次のように、行のどこでも見つかったパターンと連携したいとします。

子供の鬼

11 hello
wonderful22
beach 33 front
to44day
is55
gr 66 eat

軽く叩く

11
44
55

出る

11 hello+
wonderful22
beach 33 front
to44day+
is55+
gr 66 eat

答え1

バッシュ構文:

sed -f <(printf 's/^%d\>.*/&+/\n' $(<pats)) inp

内部部分は、<()その行を変換するためにsedプログラムを印刷します。

$ printf 's/^%d\>.*/&+/\n' $(<pats)
s/^11\>.*/&+/
s/^44\>.*/&+/
s/^55\>.*/&+/

構文<()はbashプロセスオーバーライドなので、コマンドの出力を取得してファイルからインポートしたかのように使用できます。その後、sed -f sed_program inp実際にファイルを変換する必要があります。

答え2

awk 'NR==FNR {pats[$1]++; next} $1 in pats {$2=$2"+"} 1' pats inp
11 hello+
22 wonderful
33 beach
44 today+
55 is+
66 great

各行の位置が一致しているかどうかを確認するには、基本的にinp同様のアプローチを使用できますが、抽出部分を使用して比較できます。match

awk 'NR==FNR {pats[$1]++; next} match($0,/[0-9]+/) && substr($0,RSTART,RLENGTH) in pats {$0=$0"+"} 1' pats inp2
11 hello+
wonderful22
beach 33 front
to44day+
is55+
gr 66 eat

(合わせたい場合普段着modepatsの場合は、arrayの要素を明示的に繰り返すなど、他のアプローチが必要ですpats。 )

答え3

この試み...

awk 'NR==FNR{Arr[$0];next}{for(i=1;i<=NF;i++)for(j in Arr)if(match($i,j)){F=1;$0=$0"+"}else{F=0}}1' pat.txt input.txt
    11 hello+
    wonderful22
    beach 33 front
    to44day+
    is55+
    gr 66 eat

関連情報