Linux

按行號將一個文件中的行替換為另一個文件中的行

  • February 10, 2021

我有一個包含很多行的 fileA.txt,我想用第二個文件 fileB.txt 中的其他特定行替換特定行,該文件也有很多行

例如:fileA.txt

Italy
Korea
USA
England
Peru
Japan
Uruguay

文件B.txt

Argentina
Switzerland
Spain
Greece
Denmark
Singapore
Thailand
Colombia

我想用第二個文件中的第 1、2、5 和 8 行替換第一個文件中的第 2、4、5 和 7 行:

輸出:

Italy
Argentina
USA
Switzerland
Denmark
Japan
Colombia

我想我可以用 awk 或 sed 做到這一點,但如果 awk 這個程式碼似乎沒有提供第二個文件行的資訊:

awk 'NR==FNR{ a[$2]=$1; next }FNR in a{ $0=a[FNR] }1' fileA.txt fileB.txt

有什麼建議嗎?

使用awk

awk -v a='2,4,5,7' -v b='1,2,5,8' '
BEGIN { split(a, ax, ","); split(b, bx, ",");
       for(n in ax) mapping[ bx[n] ] =ax[n];
};
NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };
{ print (FNR in hold)? hold[FNR]: $0; }' fileB fileA

在這裡,我們將行號作為awk -v變數傳遞給 (for fileA a='...') 和b='...'(for fileB),然後我們split()將它們放入一個以逗號字元作為分隔符的數組中(請注意,aandb是變數,而現在axandbx是數組)。

mapping然後我們從ax和數組中建構另一個數組,bx以映射文件A中應該替換的行與文件B中的行;

現在數組的鍵(或索引)*mapping*是fileB的行號,這些鍵的值是fileA的行號,如下所示:

mapping數組是:

Key    Value
1      2
2      4
5      5
8      7

所以現在我們需要什麼,也就是說,只是從 fileB 中讀取與上面的鍵匹配的行號(FNRs of 1, 2, 5and 8),所以我們這樣做:

NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };

好的,現在 的值是mapping[FNR]多少?如果您檢查mapping上面的數組,那將是:

mapping[1] --> 2; then-we-have    hold[ mapping[1] ] --> hold[2]=$0
mapping[2] --> 4; then-we-have    hold[ mapping[2] ] --> hold[4]=$0
mapping[5] --> 5; then-we-have    hold[ mapping[5] ] --> hold[5]=$0
mapping[8] --> 7; then-we-have    hold[ mapping[8] ] --> hold[7]=$0

所以我們使用數組的值作為mapping數組的鍵,hold數組hold現在包含:

Key     Value
2       Argentina
4       Switzerland
5       Denmark
7       Colombia

現在最後一步是使用hold數組中的鍵作為 fileA 中的匹配行號,如果在數組中找到該行號,則用數組中該鍵的值替換該行,hold如果未找到則列印該行本身(三元運算符:condition? if-true : if-false),我們這樣做:

{ print (FNR in hold)? hold[FNR]: $0; }

引用自:https://unix.stackexchange.com/questions/633648