テキストデータセットの作成者別にドキュメントセットを計算しようとしています。著者名とタイトルの付いた目次があります。各作成者のディレクトリにある文書数を出力したいと思います。 ls コマンドのファイルの例を次に示します。
'Winston Churchill___Richard Carvel, Complete.txt'
'Winston Churchill___The Celebrity, Complete.txt'
'Winston Churchill___The Crisis, Complete.txt'
'Winston Churchill___The Crossing.txt'
'Winston Churchill___The Dwelling Place of Light, Complete.txt'
'Winston Churchill___The Inside of the Cup, Complete.txt'
'Zane Grey___Betty Zane.txt'
'Zane Grey___Desert Gold.txt'
'Zane Grey___Riders of the Purple Sage.txt'
'Zane Grey___Tales of Fishes.txt'
'Zane Grey___Tales of lonely trails.txt'
'Zane Grey___The Border Legion.txt'
'Zane Grey___The Call of the Canyon.txt'
'Zane Grey___The Day of the Beast.txt'
'Zane Grey___The Desert of Wheat.txt'
文書が3000を超えるため、手動で数えることはできません。
答え1
以下はトリックを実行する必要があります(.txt
サフィックス、サブフォルダなし、および作成者の区切り文字として「___」と仮定)。
find -maxdepth 1 -mindepth 1 -name '*.txt' -printf '%f\n' | awk -F'___' '{print $1}' | sort | uniq -c
読みやすくするために、別の行に:
find ./ -maxdepth 1 -mindepth 1 -name '*.txt' -printf '%f\n' |
awk -F'___' '{print $1}' |
sort |
uniq -c
できること:
find
すべてのファイルを一覧表示するために使用されます。a)
.txt
- サフィックス (-name '*.txt'
)b) サブディレクトリではなく現在のディレクトリ(
-maxdepth 1
)c) ディレクトリ自体をリストしない(
-mindepth 1
)d)ディレクトリ名の前と改行なしでファイル名を印刷します。
-printf '%f\n'
使用
awk
a) define three underscores as field separator `-F'___'` b) print first field (author) only `'{print $1}'`
sort
出力は確実ですuniq
一意の項目のみをリストし、-c
数を計算するために使用されます。
もちろん、ファイル名に改行や同様の文字が含まれている場合は、ゼロで終わるリストを使用する必要があります。したがって、慎重に扱うには、次のようにします。
find ./ -maxdepth 1 -mindepth 1 -name '*.txt' -printf '%f\000' | awk 'BEGIN {RS="\x00" ; FS="___" ; ORS=\x00"} {print $1}' | sort -z | uniq -zc | tr '\000' '\n'
しかし、私はこれが過度に過ぎていると思います。
答え2
$ for name in *___*.txt; do printf '%s\n' "${name%%__*}"; done | uniq -c
6 Winston Churchill
9 Zane Grey
これは、著者名を印刷し、uniq -c
各名前の出現回数を計算します。___
ファイル名に最初に表示されるすべてのエントリ(下線3つ)を削除して、各ファイル名からこの名前を取得します。
uniq -c
ファイル名ワイルドカード拡張結果は常にアルファベット順にソートされるため、呼び出し前にループの出力をソートする必要はありません。
これは、作成者名に改行文字が含まれていないと仮定します。しかし、3つの下線の後には改行が許可されます。