Bash
如果在輔助列表中找到匹配項,則替換主列表中的欄位
我有一個包含大約幾千行的列表,每行包含 4 或 5 個欄位。我還有第二個列表,包含幾行,只有 1 個欄位。兩個列表都將儲存在一個變數中。
第一個列表:
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
第二名單:
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"
您會考慮使用
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
、換行符和所有內容讀入 shell 變數shortlistOneString
。- 在
BEGIN
塊中,我們將 的值拆分"$shortlistOneString"
為我們稱為的數組a
;這個數組有n
元素,我們可以用 訪問第i個元素a[i]
。這個塊只執行一次,在awk
正確的輸入開始之前。- 單獨
awk
將每一行解析為一個特殊的保留數組;對於任何輸入行,這個數組都有NF
元素,我們可以用;訪問第j個元素$j
甚至可以覆蓋這些元素。- 對於每一行,
awk
將執行第二個塊中的語句(第一個語句是found=0
,最後一個語句是- 如果第j個欄位等於
oldv
,我們用 覆蓋該欄位newv
,然後停止查找。因為awk
沒有break
Bash(例如)所具有的多級,所以我們使用一個名為 的輔助變數,我們為每一行found
重置它。0
- 無論我們是否覆蓋了一個欄位,我們
- 此解決方案比您要求的更通用。您可以通過僅檢查每行的最後一個欄位
$(NF)
和倒數第二個 欄位來收緊它$(NF-1)
;您甚至可以分別對欄位位置進行硬$5
編碼$4
。