Text-Processing
有條件地將 file1 的行替換為 file2 的相應行
例如,我有兩個文件:
文件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
表達式執行以下操作:
- 如果目前行以 開頭
X
,則第一個替換將刪除所有內容,包括第一個製表符。paste
如果第一列是 ,則這有效地將輸出的第二列移動到第一列X
。- 第二個表達式刪除製表符及其後的任何內容。這會刪除我們不感興趣的數據。
如果 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 是第二個文件名。