Text-Processing

刪除重複的行,同時保持行的順序

  • November 23, 2021
[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-

這個怎麼運作:

  1. 在 GNU 系統上,cat -n將在每行前面加上一定數量的空格和*<tab>*字元的行號。cat將此輸入表示形式通過管道傳輸到sort.
  2. sort-k2選項指示它在排序時僅考慮從第二個欄位到行尾的字元,並sort預設在空格*(或cat’ 的插入空格和**<tab>**)*上拆分欄位。

後跟 時-k1nsort首先考慮第二個欄位,然後是第二個(在相同-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

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