たとえばここで、各行の重複を削除するにはどうすればよいですか?
1 1 1 2 1 2 3
5 5 4 1 2 3 3
この出力を取得したい:
1 2 3
5 4 1 2 3
たくさんの行(100,000)があり、各行に一意の値が必要です。 Perlが最速かもしれませんが、PerlまたはBashでそれを行うにはどうすればよいですか?
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
_
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
行は副産物としてソートされます。