Linux
按重複對列進行排序並保留第一次出現
我有一個文件如下
1:A 2:B 3:A
我需要輸出為:
1:A 2:B
由於第三個條目第二列包含 A,就像第一個條目一樣,它會刪除它。它還需要區分大小寫。
這是一個非常大的文件,所以節省時間會很好。
我已經嘗試過了,但它似乎只列印了獨特的線條
sort -u -t':' -k3,3 file
使用
sort
正如 Ed 在他的評論中所說,您的
sort
命令正在對第三個欄位進行排序,而實際上您只有兩個欄位(:
欄位分隔符)。因此,要修復它,請替換3
為2
for 鍵。但是,當記錄按其鍵值而不是按行/記錄號排序時,源文件中的原始記錄順序就會混亂:
$ sort -u -t':' -k2,2 test.txt 1:A 2:B 6:C 5:a 4:b $
這可能不是你想要的。然而,這很容易通過
sort
再次管道輸出來解決:$ sort -u -t':' -k2,2 test.txt | sort 1:A 2:B 4:b 5:a 6:C $
注意:正如您所說的那樣,您有一個大文件,為了加快速度,您可能需要考慮使用
--parallel
標誌1:sort --parallel=<n> -u -t':' -k2,2 test.txt | sort --parallel=<n>
<n>
您可用的核心數量是什麼時候。使用
awk
如果原始數據位於名為 的文件中,則擴展您的範例文件
test.txt
,如下所示:1:A 2:B 3:A 4:b 5:a 6:C
並且,再次將
:
視為欄位分隔符,然後您可以使用awk
2。例如這一行:
awk 'BEGIN{FS=":"}{if (!seen[$2]++)print $0}' test.txt
給出以下結果:
$ awk 'BEGIN{FS=":"}{if (!seen[$2]++)print $0}' test.txt 1:A 2:B 4:b 5:a 6:C $
您可以通過查看邏輯來了解其工作原理,使用
$ awk 'BEGIN{FS=":"}{print !seen[$2]++}' test.txt 1 1 0 1 1 1 $
- 首先,欄位分隔符用 指定
FS=":"
。- 其次,否定運算符為尚未看到的第二個欄位條目提供“真實”結果。
- 最後,
print $0
列印整個記錄,即目前行。將其放入 shell 腳本3而不是
awk
腳本會給出:#!/bin/sh awk -F':' ' (!seen[$2]++) { print $0 } ' "$1"
參考資料: