何についてawk
を使用していますか?あなたは本当に、単にFIRST発生を得ることができます:あなたは「グレップ」を「見つける」使用としていることを考えると
[[email protected] ~]$ sort -r data1 | awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' | sort
./501.res/1.bin
./503.res/2.bin
./504.res/1.bin
[[email protected] ~]$
:
[[email protected] ~]$ cat data1
./501.res/1.bin
./503.res/1.bin
./503.res/2.bin
./504.res/1.bin
[[email protected] ~]$ awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' data1
./501.res/1.bin
./503.res/1.bin
./504.res/1.bin
[[email protected] ~]$
は、ある種のカップルを通してあなたがパイプをできた最後の出現を取得するにはおそらくこれを行うことができます:
find . -name \*.bin -type f -print | sort -r | awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' | sort
これはどのように機能しますか?
find
コマンドはグロブであなたのファイルを選択する機能など、多くの便利なオプションがあり、ファイルの種類を選択するには、などがその出力あなたが既に知っている、そしてそれはsort -r
への入力になります。
まず、入力データを逆順に並べ替えます(sort -r
)。これにより、任意のディレクトリ内で、最も番号の付いたファイルが最初に表示されることが保証されます。その結果はawkに送られます。 FSはフィールド区切り文字で、$2
を "/ 501"、 "/ 502"などに変換します。Awkスクリプトのセクションはcondition {action}
という形式のセクションがあり、入力の各行ごとに評価されます。条件がない場合、アクションはすべての行で実行されます。 "1"が条件であり、アクションがない場合は、行を出力します。次のようにこのスクリプトが実行壊れている:
a[$2] {next}
- 添字$ 2(すなわち、「/ 501」)が存在する、との配列a
だけで次の行にジャンプします。そうでなければ...
{a[$2]=1}
は - 行を印刷する - 将来的には最初の条件が真と評価されますように、そして...
1
、1に配列に添字$ 2セット。
このawkスクリプトの出力は、必要なデータですが、逆の順序です。最終的にsort
は、あなたが期待する順番に物事を戻します。
今、パイプの数が多いので、何百万行もの入力を同時に処理するように頼んだら、ソートは少しでもリソースが空いている可能性があります。このソリューションは、ファイル数が少ない場合は完全に十分ですが、大量の入力を処理している場合はお知らせください。オールインワンawkソリューションを考え出すことができます(これは60秒以上かかる場合があります書き込む)。
UPDATE
これは機能的に同じですがパーデニスの賢者の助言、私は上記に含まawkスクリプトが
BEGIN{FS="."} $2 in a {next} {a[$2]} 1
に
BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1
からそれを変更することで改善することができました利点は、値を代入するのではなく配列メンバを定義するだけで、メモリやCPUを節約できますあなたのawkの実装が保留中です。とにかく、それはきれいです。
'{next {}}で$ 2を使って配列に要素の存在をテストする方が良いです。このようにすると、単に新しい配列要素を参照するだけで新しい配列要素が作成されるわけではありません。これは私がこれについて議論していた頃のことです。ちなみに、 'のように'を使うと、 '{a [$ 2] = 1}'の代わりに '{a [$ 2]}'を使うことができますが、どちらでも動作します。 –
@DennisWilliamson、AH、先日、あなたが得ていたことを理解しました。ポインタに感謝します。 :) – ghoti