awk - 如果列1我不知道____ualtothepreviouscolumn1一世sn○噸eq你一個l噸○噸Heprev一世○你sC○l你米n1 is not equal to the previous column1 然後列印整個前一…
我正在嘗試在 Linux 上編寫一個 awk 程序,如果第一列中的字元串與上一行第一列中的字元串不同,它將列印整個上一行。
另一種說法是,每當第一列相等時,列印整個匹配列的最後一行並丟棄前一個相等的列。
我使用了這段程式碼:
awk 'BEGIN { FS=OFS=";" } $1==last{next} {last=$1} {print last}' test.txt
但我想它只是列印前一行的第一列。如何列印整個前一行?
我的輸入文件,
test.txt
看起來像這樣:818522;"Joey"; 817399;"john"; 817399;"CCE"; 817399;"smith"; 817399;"Ron"; 817400; 817400; 817400; 818000;"ODC"; 890021; 890021; 890021;"rachel"; 890021;"monica"
期望的輸出:
818522;"Joey"; 817399;"Ron"; 817400; 818000;"ODC"; 890021;"monica"
$ awk -F';' '$1 != l1 && l1 != "" { print l0 }; {l1 = $1; l0 = $0}; END {if ($1 != $l1) {print}}' test.txt 818522;"Joey"; 817399;"Ron"; 817400; 818000;"ODC"; 890021;"monica"
該
-F';'
選項將 awk 的輸入欄位分隔符 (FS
) 設置為分號。awk 自動拆分每個輸入行FS
並將欄位分配給 $ 1, $ 2、 $ 3, ….., $ n.變數
l1
和l0
用於保存第一個欄位 ($1
) 和整行 ($0
)。在大多數情況下,
awk
腳本是一系列PATTERN { ACTION }
規則 - 如果 PATTERN 評估為真,則執行 ACTION。PATTERN 可以是任何評估為真或假的東西(正則表達式匹配、變數比較、計算等)。ACTION 可以是任何 awk 程式碼語句。這些規則對每一行輸入重複。請注意,PATTERN 或 ACTION 都可以是可選的 - 如果缺少 PATTERN,則將其視為評估為 true,並且始終執行 ACTION。如果缺少 ACTION,則預設操作是man awk
,或者,如果您使用 GNU awk,.info awk
還有 O’Reilly sed & awk戴爾·多爾蒂和阿諾德·羅賓斯的書)。awk 腳本的第一行測試目前行是否
$1
不等於l1
空字元串。如果兩個測試都為真,它會列印最後一個輸入行l0
. 在輸入的第一行,l1
總是空的(因為腳本的第二行還沒有執行,所以沒有給它賦值),所以什麼都不會列印(l0
反正也是空的,所以列印它只會輸出一個空行)。awk 腳本的第二行無條件地從目前輸入行設置
l1
和。l0
該腳本為每一行輸入重複這兩行程式碼。
當沒有更多輸入時,主腳本循環結束並
END {...}
執行該塊。它列印目前輸入行(即輸入的最後一行) - 目前僅當$1 != l1
但經過反思(以及一些簡短的測試)時,如果沒有該測試,它可能也可以正常工作,只是END {print}
.
您的描述與您的輸出不匹配,所以我有點困惑。根據您的描述,預期的輸出應該是:
818522;"Joey"; 817399;"Ron"; 817400; 818000;"ODC";
您不會列印任何
890021
行,因為它們是最後一行,因此它們的第一個欄位永遠不會與下一行不同。如果這確實是你想要的,你可以這樣做:$ awk -F';' '{ if($1!=last && prevLine){ print prevLine } { last=$1; prevLine=$0 } }' file 818522;"Joey"; 817399;"Ron"; 817400; 818000;"ODC";
如果您還想為最後一行添加異常,請嘗試以下操作:
$ awk -F';' '{ if($1!=last && prevLine){ print prevLine; lastPrinted=last } { last=$1; prevLine=$0 } } END{ if($1 != lastPrinted){ print } }' file 818522;"Joey"; 817399;"Ron"; 817400; 818000;"ODC"; 890021;"monica"
這個想法很簡單:如果第一個欄位不一樣
last
並且定義了prevLine
變數(所以我們不列印第一行),那麼我們列印上一行(prevLine
)並保存上一行的第一個欄位(last
) 在變數中lastPrinted
。然後,對於所有行,我們設置
last
為第一個欄位和prevLine
目前行。最後,當我們到達文件的末尾時END{}
(lastPrinted