刪除重複的行,同時保持行的順序
[root@server]# awk '!seen[$0]++' out.txt > cleaned awk: (FILENAME=out.txt FNR=8547098) fatal error: internal error Aborted [root@server]#
“伺服器”具有:8 GByte RAM + 16 GByte SWAP,x>300 GByte 可用空間,amd64,桌面 CPU。科學 Linux 6.6。沒有其他東西可以在其上執行來生成 LOAD。幾秒鐘後,Awk 中止。out.txt 約為 1.6 GB。GNU awk 3.1.7。
問題:如何在保持行順序的同時刪除重複的行?大小寫也很重要,例如:“A”和“a”是兩條不同的行,必須保留它。但是“a”和“a”是重複的,只需要第一個。
答案可能是任何東西..如果 awk 不適合這個.. 那麼 perl/sed.. 問題可能是什麼?
[root@server]# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 61945 max locked memory (kbytes, -l) 99999999 max memory size (kbytes, -m) unlimited open files (-n) 999999 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 99999999 cpu time (seconds, -t) unlimited max user processes (-u) 61945 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [root@server]#
更新:我在 RHEL 機器上試過這個,它沒有中止,但我沒有時間等待它完成.. 為什麼 SL linux 與 RHEL 不同?
更新:我正在嘗試使用 Ubuntu 14 虛擬機.. 到目前為止它可以工作!這不是 ulimit 問題:mawk 1.3.3
root@asdf-VirtualBox:~# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 51331 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 51331 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited root@asdf-VirtualBox:~#
我懷疑它會有所作為,但以防萬一,這裡是如何在 Perl 中做同樣的事情:
perl -ne 'print if ++$k{$_}==1' out.txt
awk
如果問題是將唯一行保留在記憶體中,那將與您嘗試的問題相同。因此,另一種方法可能是:cat -n out.txt | sort -k2 -k1n | uniq -f1 | sort -nk1,1 | cut -f2-
這個怎麼運作:
- 在 GNU 系統上,
cat -n
將在每行前面加上一定數量的空格和*<tab>*字元的行號。cat
將此輸入表示形式通過管道傳輸到sort
.sort
的-k2
選項指示它在排序時僅考慮從第二個欄位到行尾的字元,並sort
預設在空格*(或cat
’ 的插入空格和**<tab>**)*上拆分欄位。後跟 時
-k1n
,sort
首先考慮第二個欄位,然後是第二個(在相同-k2
欄位的情況下)它考慮第一個欄位,但按數字排序。因此,重複的行將按照它們出現的順序排列在一起。 3. 結果被傳送到uniq
- 被告知忽略第一個欄位*(-f1
- 並且也由空格分隔)* - 並導致原始文件中唯一行的列表並被傳送回sort
. 4. 這次sort
對第一個欄位*(cat
的插入行號)進行數字排序,將排序順序恢復到原始文件中的順序,並將這些結果通過管道傳輸到cut
. 5. 最後,cut
刪除由 插入的行號cat
。這是通過cut
僅從第二個欄位列印到行尾來實現的(並且cut
’ 的預設分隔符是**<tab>**字元)*。為了顯示:
$ cat file bb aa bb dd cc dd aa bb cc $ cat -n file | sort -k2 | uniq -f1 | sort -k1 | cut -f2- bb aa dd cc