次のファイルが与えられた場合:
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つ以上の連続した$i
0つ以上のスペースを検索してに置き換えます$i+
。