Awk
替換列中的模式
我需要將來自不同文件的文件中的模式替換為輸入。
讓我們說 file1 內容:
ab 10 bc 20 cd 30 de 40
文件2:
server1;10 feb 2020;disk5;123455678;comment;10;1;desc;abcde3;987654 server1;10 feb 2020;disk6;123455678;comment;10;7;desc;abcde3;987654 server1;10 feb 2020;disk10;123455678;comment;20;4;desc;abcde3;987654 server1;10 feb 2020;disk1;123455678;comment;30;5;desc;abcde3;987654 server1;10 feb 2020;disk9;123455678;comment;20;4;desc;abcde3;987654 server1;10 feb 2020;disk2;123455678;comment;40;6;desc;abcde3;987654 server1;10 feb 2020;disk5;123455678;comment;30;8;desc;abcde3;987654
在這裡,作為
;
file2 中的分隔符,我想用 file1 中的匹配值替換第 6 列。IE
server1;10 feb 2020;disk5;123455678;comment;**ab**;1;desc;abcde3;987654
我知道它可能通過
awk
/sed
。你能幫忙嗎?注意:我們不使用 GNU 版本的awk
/sed
作為它的AIX
.
本練習的難點在於如何在同一個
awk
程序中處理不同的欄位分隔符。使用 GNU
awk
:$ gawk 'FNR == NR { pat[$2] = $1; next } ($6 in pat) { $6 = pat[$6] } { print } ENDFILE { OFS = FS = ";" }' file1 file2 server1;10 feb 2020;disk5;123455678;comment;ab;1;desc;abcde3;987654 server1;10 feb 2020;disk6;123455678;comment;ab;7;desc;abcde3;987654 server1;10 feb 2020;disk10;123455678;comment;bc;4;desc;abcde3;987654 server1;10 feb 2020;disk1;123455678;comment;cd;5;desc;abcde3;987654 server1;10 feb 2020;disk9;123455678;comment;bc;4;desc;abcde3;987654 server1;10 feb 2020;disk2;123455678;comment;de;6;desc;abcde3;987654 server1;10 feb 2020;disk5;123455678;comment;cd;8;desc;abcde3;987654
在這裡,我們開始讀取第一個文件,在關聯數組中填充
pat
我們希望稍後在第 6 列中替換的內容。鍵是我們替換的東西,值是我們替換它們的東西。當 GNU
awk
讀完一個文件時,它會執行該ENDFILE
塊,如果它存在的話(還有一個BEGINFILE
塊在某些情況下可能有用)。ENDFILE
並且BEGINFILE
就像“本地文件”BEGIN
和END
塊。在這裡,我們使用
ENDFILE
將輸入和輸出欄位分隔符更改為分號。在讀取第二個文件時,我們只是測試第 6 個欄位中的數據是否可用作鍵
pat
,如果是,我們將其值替換為該鍵的值。列印第二個文件中的所有行,無論是否修改。使用非 GNU
awk
,可以這樣做:$ awk 'FNR == NR { pat[$2] = $1; next } { OFS = FS = ";"; $0=$0 } ($6 in pat) { $6 = pat[$6] } { print }' file1 file2 server1;10 feb 2020;disk5;123455678;comment;ab;1;desc;abcde3;987654 server1;10 feb 2020;disk6;123455678;comment;ab;7;desc;abcde3;987654 server1;10 feb 2020;disk10;123455678;comment;bc;4;desc;abcde3;987654 server1;10 feb 2020;disk1;123455678;comment;cd;5;desc;abcde3;987654 server1;10 feb 2020;disk9;123455678;comment;bc;4;desc;abcde3;987654 server1;10 feb 2020;disk2;123455678;comment;de;6;desc;abcde3;987654 server1;10 feb 2020;disk5;123455678;comment;cd;8;desc;abcde3;987654
這有點低效,但它的作用是對於第二個文件中的每一行,它設置
OFS
並FS
重新;
拆分輸入。一個稍微更有效(但仍然醜陋)的變體是只為第二個文件中的第一行設置
OFS
和:FS
awk 'FNR == NR { pat[$2] = $1; next } FS != ";" { OFS = FS = ";"; $0=$0 } ($6 in pat) { $6 = pat[$6] } { print }' file1 file2
假設所有 $6 值都包含在 file1 中,請嘗試
awk 'FNR == NR {T[$2] = $1; next} {$6 = T[$6]} 1' file1 FS=";" OFS=";" file2