GNU/Linux >> Linux の 問題 >  >> Linux

特定の列の重複フィールドを削除しますか?

特定の列(例では$ 2)から重複フィールド(カンマ区切り)を削除したいのですが。

入力ファイル:

A    1,2,3,4   
B    4,5,6,3
C    2,15

期待される出力:

A    1,2,3,4
B    5,6
C    15

承認された回答:

perl -lpe 's/sKS+/join ",", grep {!$seen{$_}++} split ",", $&/e'

上記のように実行できます:

$ perl -lpe 's/sKS+/join ",", grep {!$seen{$_}++} split ",", $&/e' afile 
A    1,2,3,4
B    5,6
C    15

仕組み

最初にperlを呼び出す -lpeを使用 次の3つのことを行います。

  • -l[octal] 行終了処理を有効にし、行ターミネータを指定します
  • -p -nのようなループを想定しますが、sedのように行も出力します
  • -e program 1行のプログラム(複数の-eを許可、programfileを省略)

これは基本的にファイルを取り込み、改行を取り除き、行を操作し、完了したら改行文字をファイルに戻します。つまり、ファイルをループして、それぞれに対してPerlコードを順番に実行するだけです。

実際のPerlコードについて:

  • s 間隔文字を意味します(5文字の[ fnrt] およびv perlの新しいバージョン 、[[:space:]]のように 。
  • K Kの左側にあるものを保持し、$&に含めないでください
  • S+ セットに含まれていない1つ以上の文字[fnrtv]

join ",", 結果を取得し、各フィールドをカンマで区切るように再結合します。

split ",", $& S+によって検出された一致を取得します カンマなしでフィールドだけに分割します。

grep {!$seen{$_}++} 各フィールドの番号を取得し、ハッシュに追加します。$seen{} ここで、各フィールドの番号は$_ それぞれを見ていきます。フィールド番号が「表示」されるたびに、++を介してカウントされます 演算子、$seen{$_}++

grep {!$seen{$_}++} 一度しか表示されなかった場合、フィールド値を返します。

何が起こっているかを確認するために変更

この変更された忌まわしきものを使用すると、このPerlワンライナーがファイルの行を横切って移動するときに何が起こっているかを確認できます。

$ perl -lpe 's/sKS+/join ",", grep {!$seen{$_}++} split ",", $&/e; @a=keys %seen; @b=values %seen; print "keys: @a | vals: @b"' afile 
keys: 4 1 3 2 | vals: 1 1 1 1
A    1,2,3,4
keys: 6 4 1 3 2 5 | vals: 1 2 1 2 1 1
B    5,6
keys: 6 4 1 3 2 15 5 | vals: 1 2 1 2 2 1 1
C    15

これは、$seen{}の内容を示しています。 ファイルからの行の処理の最後に。ファイルの2行目を見てみましょう。

B    4,5,6,3

そして、これが私の修正バージョンがその行を次のように示しているものです:

keys: 6 4 1 3 2 15 5 | vals: 1 2 1 2 2 1 1

つまり、フィールド#6(1回)、フィールド#4(2回)など、およびフィールド#5(1回)を見たことがあるということです。したがって、grep{...} 結果を返します。この配列がこの行に存在する場合(4,5,6,3)、および1回だけ表示された場合(6,1,15,5)にのみ、この配列からの結果が返されます。これら2つのリストの共通部分は(5,6)であるため、grepによって返されるのはそれです。 。

参考資料

  • perlre – perldoc.perl.org
関連:ファイルをインプレースで変更する方法は?
Linux
  1. APTで期限切れのキーを削除します

  2. テキストファイル内の重複行を削除するにはどうすればよいですか?

  3. 並べ替えなしで1列内の重複に基づいて行を削除しますか?

  1. 指定された列が大文字で始まる場合に行を印刷しますか?

  2. 注文を維持しながら、隣接する重複行を削除しますか?

  3. 出力を列で並べ替えますか?

  1. Linuxで重複する写真を見つけて削除する方法

  2. Linuxコマンドを使用してプレーンテキストファイルから重複した単語を削除する方法

  3. 列ごとに「ユニーク」にする方法はありますか?