我正在尝试按作者从文本数据集中计算一组文档。我有一个书籍目录,由作者命名,后跟标题。我想输出每个作者目录中的文档数量。可以在此处查看 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
计算每个姓名的出现次数。通过删除___
文件名中第一次出现(三下划线)的所有内容,从每个文件名中获得该名称。
uniq -c
不需要在调用之前对循环的输出进行排序,因为文件名通配扩展的结果始终是排序的(按字典顺序)。
这假设作者的名字不包含换行符。不过,在三重下划线之后允许换行。