行の順序を維持しながら重複行を削除する

行の順序を維持しながら重複行を削除する
[root@server]# awk '!seen[$0]++' out.txt > cleaned
awk: (FILENAME=out.txt FNR=8547098) fatal error: internal error
Aborted
[root@server]#

「サーバー」には8GB RAM + 16GB SWAP、x> 300GBの空き容量、amd64、デスクトップCPUがあります。サイエンティフィックLinux 6.6。その上にロードする他の実行項目はありません。数秒後に awk が停止します。 out.txtは約1.6GBです。GNUを目覚めさせる3.1.7。

質問:行の順序を維持しながら重複行を削除する方法は?大文字と小文字も重要です。たとえば、「A」と「a」は2つの異なる行なので、維持する必要があります。ただし、「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の問題ではありません。モック 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:~# 

ベストアンサー1

これが違いをもたらすかどうかは疑問ですが、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各行の前に行番号が続き、その後にスペースが続きます。<タブ>特徴。catこの入力表現をsort

  2. sortオプションは、-k2ソート時に2番目のフィールドから行末までの文字のみを考慮し、デフォルトでスペースにsortフィールドを分割するように指示します。(またはcatスペースを挿入して<タブ>)
    続くと、-k1n2sort番目のフィールドが最初に考慮され、次に(-k2同じフィールドの場合)最初のフィールドが考慮されますが、数字でソートされます。したがって、重複した行は表示される順序で並べ替えられます。

  3. 結果は次にパイプされますuniq。最初のフィールドを無視するように求められます。-f1- スペースで区切ることもできます)- 元のファイルの一意の行のリストを生成し、それを再度sort
  4. 今回はsort最初のフィールドをソートします。(cat行番号の挿入)数値的にソート順序を元のファイルの順序に復元し、結果をcut
  5. 最後にcut挿入された行番号を削除しますcat。これは、cut2番目のフィールドから行末までのみ印刷することで可能です。cutデフォルトの区切り記号は次のとおりです。<タブ>特徴)

表示するには:

$ 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

おすすめ記事