列の重複行のマージ

列の重複行のマージ

次のファイルが与えられた場合:

x y y z x
x x y z z y
x x x z y
y z z y x x x
x x x x x

私は出力が次のようになります:

x y+ z x
x+ y z+ y
x+ z y
y z+ y x+
x+

awkまたはPerlを使ってこれを行うことはできますか?つまり、連続して同じ値をどのくらい見つけてマージできますか?

答え1

sed 's/\(.\)\( \1\)\{1,\}/\1+/g' <in >out

x y+ z x
x+ y z+ y
x+ z y
y z+ y x+
x+

BSDまたはGNUの使用sed:

sed -Ee's/(.)( \1)+/\1+/g' <in >out

任意のフィールド長を使用するには、単に任意のフィールド長を使用するだけです。

sed -Ee 's/(...)( \1)+/\1+/g' <<""
xxx yyy yyy zzz xxx
xxx xxx yyy zzz zzz yyy
xxx xxx xxx zzz yyy
yyy zzz zzz yyy xxx xxx xxx
xxx xxx xxx xxx xxx

xxx yyy+ zzz xxx
xxx+ yyy zzz+ yyy
xxx+ zzz yyy
yyy zzz+ yyy xxx+
xxx+

または、2行目の@terdonの入力を少し変更します。

sed -Ee's/(([^ ]+ *)+)( +\1)+/<\1>+/g' <<""
foo foo foo bar foo
bar foo bar foo
foo foo x x x bar

<foo>+ bar foo
<bar foo>+
<foo>+ <x>+ bar

答え2

このperlバージョンでは、単一文字のフィールド長だけでなく、任意のフィールド長も処理できます。

$ perl -lpae 'for $i (@F){s/($i\s*){2,}/$i+ /g}' file 
x y+ z x
x+ y z+ y
x+ z y
y z+ y x+ 
x+ 

より複雑なファイルの場合:

$ cat file
foo foo foo bar foo
bar foo bar bar foo
foo foo x x x bar
$ perl -lpae 'for $i (@F){s/($i\s*){2,}/$i+ /g}' file 
foo+ bar foo
bar foo bar+ foo
foo+ x+ bar

説明する

-l各入力行の改行を切り取り、空白-aの入力フィールドを配列に分割し@F-p与えられたスクリプトを適用して各入力行を印刷します-e

スクリプト自体は各入力フィールド(配列@F)を繰り返し、各フィールドを$i.replaceとして保存すると、2つ以上の連続した$i0つ以上のスペースを検索してに置き換えます$i+

関連情報