web-dev-qa-db-ja.com

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

それぞれに何回も繰り返される名前の列が1つあるファイルがあります。同じ名前の他のリピートに隣接していない同じ名前の他のリピートを維持しながら、各リピートを1つに圧縮したい。

例えば。左側を右側に向けたい:

Golgb1    Golgb1    
Golgb1    Akna
Golgb1    Spata20
Golgb1    Golgb1
Golgb1    Akna
Akna
Akna
Akna
Spata20
Spata20
Spata20
Golgb1
Golgb1
Golgb1
Akna
Akna
Akna

これは私が使ってきたものです:Perl -ne 'print if ++$k{$_}==1' file.txt > file2.txtただし、この方法では、左から1つの代表のみが保持されます(つまり、Golb1とAknaは繰り返されません)。

複数の隣接しないブロックで繰り返される名前を維持しながら、各ブロックの一意の名前を維持する方法はありますか?

11
Age87

uniqがこれを行います:

$ uniq inputfile
Golgb1
Akna
Spata20
Golgb1
Akna
23
DopeGhoti

Awkソリューション:

awk '$1 != name{ print }{ name = $1 }' file.txt

出力:

Golgb1
Akna
Spata20
Golgb1
Akna
9
RomanPerekhrest

これを試してください-前の行を保存して現在の行と比較してください

$ Perl -ne 'print if $p ne $_; $p=$_' ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

uniqもタグ付けしました-試しましたか?

$ uniq ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna
6
Sundeep

sedを使用すると、次のように実行できます。

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

ここでは、パターンスペースにいつでも2行あります。それらの間の比較が失敗した場合、最初の1つを印刷し、それを前からチョップし、戻って次の行をパターンスペースに追加します。すすぎ...繰り返し

SlurpモードでPerlを使用すると、ファイル全体が、比較を行う正規表現が適用される1つの長い文字列として扱われます。

Perl -0777pe 's//$1/ while /^(.*\n)\1+/gm' input_file
1
Rakesh Sharma

Rakesh Sharmaのsedソリューションに関する質問。

次のような入力ファイルがあるとします。

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.118 48.216
-126.128 48.222
-126.136 48.226

そして、あなたは出力ファイルを次のようにしたいです:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.128 48.222
-126.136 48.226

不足していることに注意してください:

-126.118 48.216

私が欲しいコマンドはあなたの解決策に似ています:

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

正しい方法で変更して両方の列を印刷することはできず、この特別な方法で列2の値のみを使用して並べ替えることはできません。任意のヒント?

0
MattS