Text-Processing

有條件地將 file1 的行替換為 file2 的相應行

  • September 24, 2018

例如,我有兩個文件:

文件1:

1
4
X
5
X
7

文件2:

2
3
5
X
X
1

我想用X相應行上的 file2 中的任何內容替換 file1 的 -lines :

結果:

1
4
5
5
X
7

我更喜歡使用 CLI 命令的解決方案,例如sed.

$ paste file1 file2 | awk -F '\t' '$1 == "X" { $1 = $2 } { print $1 }'
1
4
5
5
X
7

paste命令將生成製表符分隔的輸出

1       2
4       3
X       5
5       X
X       X
7       1

如果第一個是 character ,則awk腳本只需將第一個製表符分隔的欄位設置為第二個欄位的內容X,然後列印第一個(現在可能已修改)欄位。

glenn jackman 建議的另一種方法,它不會修改傳入的數據,而只是根據第一列中的數據選擇要列印的欄位:

$ paste file1 file2 | awk -F '\t' '{ print $1 == "X" ? $2 : $1 }'

使用 GNU sed

$ paste file1 file2 | sed -E -e '/^X/s/^[^\t]+\t//' -e 's/\t.*$//'
1
4
5
5
X
7

這兩個sed表達式執行以下操作:

  1. 如果目前行以 開頭X,則第一個替換將刪除所有內容,包括第一個製表符。paste如果第一列是 ,則這有效地將輸出的第二列移動到第一列X
  2. 第二個表達式刪除製表符及其後的任何內容。這會刪除我們不感興趣的數據。

如果 file2 適合記憶體,那麼您可以使用 awk。先讀入 file2,然後在處理 file1 時,如果看到“X”,則從 file2 數組中替換它:

$ awk 'NR == FNR { lines[NR]=$0; } NR != FNR { if ($0 == "X") print lines[FNR]; else print $0 }' file2 file1

重新格式化,即:

$ awk 'NR == FNR { lines[NR]=$0; } 
      NR != FNR { if ($0 == "X") print lines[FNR]; 
                  else           print $0 
                }' file2 file1

注意 file2 是第一個文件名;file1 是第二個文件名。

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