私があなたの意味を理解していて、頻度でソートされたアイテムのリストを取得したい場合は、次のようなものをパイプでつなぐことができます。
| sort | uniq -c | sort -k1nr
例えば:
入力:
file1
file2
file1
file1
file3
file2
file2
file1
file4
出力:
4 file1
3 file2
1 file3
1 file4
アップデート
ちなみに、awkは何に使っていますか?
find . -name 'quest*' | cut -d_ -f1 | sort | uniq -c | sort -k1nr | head -n10
より頻繁に見つかった10個のアイテムを返します。
アップデート
これははるかに改良されたバージョンです。唯一の欠点は、発生数でソートされていないことです。しかし、私はそれを修正する方法を理解するつもりです:)
find . -name 'question*' | sort \
| sed "s#\(.*/question\([0-9]\+\)_[0-9]\+\)#\2 \1#" \
| awk '{ cnt[$1]++; files[$1][NR] = $2 } END{for(i in files){ print i" ("cnt[i]")"; for (j in files[i]) { print " "files[i][j] } }}'
アップデート
〜140万レコード(23インチかかりました)でテストした後、awkはすべてのグループ化などを処理するには非効率的であると判断したので、Pythonで次のように記述しました。
#!/usr/bin/env python
import sys, re
file_re = re.compile(r"(?P<name>.*/question(?P<id>[0-9]+)_[0-9]+)")
counts = {}
files = {}
if __name__ == '__main__':
for infile in sys.stdin:
infile = infile.strip()
m = file_re.match(infile)
_name = m.group('name')
_id = m.group('id')
if not _id in counts:
counts[_id] = 0
counts[_id]+=1
if not _id in files:
files[_id] = []
files[_id].append(_name)
## Calculate groups
grouped = {}
for k in counts:
if not counts[k] in grouped:
grouped[counts[k]] = []
grouped[counts[k]].append(k)
## Print results
for k, v in sorted(grouped.items()):
for fg in v:
print "%s (%s)" % (fg, counts[fg])
for f in sorted(files[fg]):
print " %s" % f
これは、分割、グループ化、および並べ替えのすべての作業を実行します。また、同じ入力ファイルで実行するのに約3インチかかりました(すべての並べ替え機能が追加されています)。
さらに高速が必要な場合は、Cythonでコンパイルしてみてください。これは、通常、少なくとも30%高速です。
更新-Cython
はい、Cythonで試してみました。
上記のファイルをとして保存するだけですcalculate2.pyx
。同じフォルダに、以下を作成しますsetup.py
。
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [Extension("calculate2", ["calculate2.pyx"])]
)
そしてランチャースクリプト(私はそれに名前を付けましたcalculate2_run.py
)
import calculate2
import sys
if __name__ == '__main__':
calculate2.runstuff(sys.stdin)
次に、cythonがインストールされていることを確認し、以下を実行します。
python setup.py build_ext --inplace
これにより、とりわけcalculate2.so
ファイルが生成されます。
ここで、calculate2_run.py
通常どおりに使用します(findからの結果をパイプするだけです)。
同じ入力ファイルで、さらに最適化せずに実行しました。今回は、1.99インチかかりました。