回答:
awkを使用するオプションは次のとおりです。
awk '{ while(++i<=NF) printf (!a[$i]++) ? $i FS : ""; i=split("",a); print ""}' infile > outfile
編集、コメント付きで更新:
while (++i<=NF)
$ 0がawkの完全な行であるため、whileループを初期化し、「i」をプリクリメントします。
したがって、$ 1(最初のフィールド)から始まります。行を最後までループします(「フィールド数」のawkに組み込まれている「NF」以下)。デフォルトのフィールドセパレータはスペースです。デフォルトのセパレータは簡単に変更できます。
printf (!a[$i]++) ? $i FS : ""
これは三項操作です。
したがって、入力が配列!a[$i]++
にない場合は$ iを出力し、入力されている場合は ""を出力します。(この方法が気に入らない場合は!
、削除して元に戻すことができ$i FS : ""
ます)。
i=split("",a)
通常、それはNULLスプリットです。この場合、次の行のIがリセットされます。
print ""
出力の行を終了します(実際には100%の理由ではありません)。そうしないと、次の出力が得られます。
1 2 3 5 4 1 2 3
の代わりに
1 2 3
5 4 1 2 3
!false
、比較後に増分が行われます。ループが次に同じ番号を見つける!true
と、インデックスに対応する値が前回値に設定されていたため、比較が返されます。フィールドは再びインクリメントされますが、この「合計カウント」は後で使用されません(ただし、問題はありません)。
a
、次の行の繰り返しのために配列が削除されます。split("",a)
は、配列を削除するための速記ですa
(注意については、ドキュメントを参照してください)。副作用として、この操作もを返します0
。次の反復にi
設定する必要がある0
ため、split()
呼び出しは個別のi=0
呼び出しの代わりに割り当てに代わりに使用され、一部の文字が保存されます(おそらく読みやすくなります)。
以来ruby
、私の知っているすべてのLinuxディストリビューションが付属しています:
ruby -e 'STDIN.readlines.each { |l| l.split(" ").uniq.each { |e| print "#{e} " }; print "\n" }' < test
ここに、test
要素を含むファイルがあります。
このコマンドの機能を説明するには、Rubyは左から右にほとんど読み込めますが、
< test
シェルから取得します)split(" ")
)print "#{e} "
)純粋なbashではありませんが、...:
while read line; do
printf "%s\n" $line | sort -u | tr '\n' ' '
echo ''
done < file
行は副産物としてソートされます。
awk
、テストと操作の順序、三項演算子、split("",a)
配列をリセットする癖(およびリセットの戻り値i
)および特殊変数NF
and に依存しているため、あまり慣れていない人にはまったく読めませんFS
。そのような説明は答えをさらに良くします!