約数千の行を含むリストがあり、各行には4〜5個のフィールドが含まれています。複数の行と1つのフィールドのみを持つ2番目のリストもあります。どちらのリストも変数に保存されます。
最初のリスト:
item_1 something something value something
item_2 something something value
item_3 something something value something
item_4 something something value something
...
item_2155 something something value
item_2156 something something value something
2番目のリスト:
item_3
item_2155
望ましい最終結果:
item_1 something something value something
item_2 something something value
item_3 something something new_value something
item_4 something something value something
...
item_2155 something something new_value
item_2156 something something value something
whileループでsedを使用しようとしています。ある程度動作しますが、この方法は繰り返されるたびにリストをそれ自体に追加します。私もawkがより良い解決策だと思います。
#!/bin/bash
MYHUGELIST=$(command)
MYSHORTLIST=$(command)
while read -r line ; do
sed "/^$line /s/1of3-possible-matches/newvalue/;/^$line /s/2of3-possible-matches/newvalue/;/^$line /s/3of3-possible-matches/newvalue/" <<< "$MYHUGELIST"
done <<< "$MYSHORTLIST"
ベストアンサー1
awk
使用する代わりに使用を検討するソリューションがありますかsed
?の場合、
#!/bin/bash
read -r -d '' shortlistOneString < shortlist.txt
awk -v oldv=value -v newv=new_value -v s="$shortlistOneString" \
'BEGIN {n=split(s,a,"\n")} { \
found=0; \
for (i=1; ! found && i<=n; ++i) { \
if (a[i] == $1) { \
for (j=2; j<= NF; ++j) { \
if ($j == oldv) { \
$j = newv; found=1; break }}}}; \
print}' longlist.txt
ノート
- 改行文字とすべての内容をシェル変数
shortlist.txt
として読み込みますshortlistOneString
。 BEGIN
ブロックでは、 の値をという配列に"$shortlistOneString"
分割しますa
。この配列には、n
私たちがアクセスできる要素があります。私番目の要素はと同じですa[i]
。このブロックは、awk
入力が正しい前に一度だけ実行されます。- それ自体では、
awk
各行はすべての入力行に対して特別な保持配列に構文解析され、この配列にはNF
私たちがアクセスできる要素があります。ジェイ最初の要素は付属しています$j
。これらの要素もオーバーライドできます。 - 各行に対して、
awk
2番目のブロックの文(最初の文はfound=0
、最後の文はprint
)が実行されます。 - もしジェイ最初のフィールドはと同じです
oldv
。そのフィールドをで上書きして検索を停止newv
します。たとえば、Bashのようなマルチレベルがawk
ないため、私たちは行ごとにリセットするというbreak
ヘルパー変数を使用します。found
0
- フィールドをオーバーライドするかどうかにかかわらず、
print
1行ずつ進みます。 - このソリューションは、あなたが要求したよりも一般的です。各行の確認だけでこれを強化できます。最後のフィールド
$(NF)
そして2番目のフィールド$(NF-1)
;フィールド位置を$5
別々にハードコーディングすることもできます$4
。