2017-11-13 4 views
1

各キーワードの文字列は、文字列整数である複数行のテキストファイル(file1)を1行につき1キーワードとします。行の順序は固定されています。sedとawkを使用して先行ゼロのない整数を含むキーワードマッチング

$cat file1 
foo1 
foo2 
foo4 
foo10 

は、さらに、その行上記のキーワードのいずれかとすることができるそのうちの一つ、いくつかの空白区切り単語を含む複数行のテキストファイル(file2)を仮定する。すべての行には1つのキーワードしか含めることができず、そのキーワードは最後の単語を除いて行内のどこにでも置くことができます。キーワードがその行に存在する場合は、baz=()という語も行内に存在します。行の順序は固定されていません。

$cat file2 
foo1 bar baz=() 
bar foo4 baz=() 
foo10 qux baz=() 
foo2 baz=() 

file2の行は、キーワードn個が含まれている場合、私はをキーワードn個用語baz=()file1に持って行番号を追加したいです。

for kw in $(cat file1); do 
    lineNumbr=$(cat file1 | awk '/'$kw'/{print NR; exit}') 
    sed -i "/$kw/ s/baz\=()/baz\=($lineNumbr)/" file2 
done 

$sought_commands file1 file2 
foo1 bar baz=(1) 
bar foo4 baz=(3) 
foo10 qux baz=(4) 
foo2 baz=(2) 

は私がキーワード foo10ため foo1のマスク用語 baz=()をキーワード欠陥を持っている、次のコードを思い付きました。

$cat file2 
foo1 bar baz=(1) 
bar foo4 baz=(3) 
foo10 qux baz=(1) # ERROR! 
foo2 baz=(2) 

編集1:私は、キーワードは常に区切り文字としてfile2に空白が続いているという状況を利用して考えられたが、その後AWK-コマンドは失敗します。へ

for kw in $(cat file1); do 
    kw_adj="$kw " 
    lineNumbr=$(cat file1 | awk '/'$kw_adj'/{print NR; exit}') 
    sed -i "/$kw_adj/ s/baz\=()/baz\=($lineNumbr)/" file2 
done 

awk: cmd. line:1: /foo1 
awk: cmd. line:1:^unterminated regexp 
awk: cmd. line:1: /foo2 
awk: cmd. line:1:^unterminated regexp 
awk: cmd. line:1: /foo4 
awk: cmd. line:1:^unterminated regexp 
awk: cmd. line:1: /foo10 
awk: cmd. line:1:^unterminated regexp 
+0

(と:あなたはすでに、単純なカウントを使用して行番号を知ることができる場合も

、ループ内lineNumbr=$(...)は 、愚かですsed')あなたはおそらく何か間違っている。 – karakfa

答えて

1

問題はここにある:

sed -i "/$kw/ s/baz\=()/baz\=($lineNumbr)/" file2 

kwの値が "foo1の"、パターン/$kw/マッチ "foo10" だけでなく、foo10 qux baz=()foo10 qux baz=()を交換するとき。これがファイルに書き込まれると、baz=()は存在しなくなるので、入力から "foo10"パターンを適用すると、置き換えられることはありません。このような行

変更:

sed -i "/\<$kw\>/ s/baz\=()/baz\=($lineNumbr)/" file2 

\<...\>は、パターンマッチの単語の境界になります。 このように "foo10"は/\<foo1\>/と一致しません。完全な単語 "foo1"だけが一致します。`あなたはbashでファイルの内容をループと` awk`を使用している場合

lineNumbr=1 
for kw in $(cat file1); do 
    sed -i "/\<$kw\>/ s/baz\=()/baz\=($lineNumbr)/" file2 
    ((lineNumbr++)) 
done 
+0

説明をありがとう。あなたの解決策は私が理解できるレベルにあります。 –

1

awkレスキュー!

$ awk 'NR==FNR {a[$1]=NR; next} 
    /baz=\(\)$/ {for(i=1;i<NF;i++) 
        if($i in a) sub(/\(\)$/,"(" a[$i] ")")}1' file{1,2} 

foo1 bar baz=(1) 
bar foo4 baz=(3) 
foo10 qux baz=(4) 
foo2 baz=(2) 
関連する問題