我notes.json
在每个目录中都有一个文件。以下命令计算每个notes.json
文件的长度并返回按每个文件的行数排序的输出。
find . -name notes.json | xargs wc -l | sort -nr
它返回
789 ./D/notes.json
789 ./F/notes.json
574 ./A/notes.json
519 ./G/notes.json
现在我想包括一个搜索模式对于里面的内容notes.json
并希望返回每个notes.json
文件的排序行数。
我试过find . -name notes.json | xargs cat | jq '."text1[]"' | wc -l
。但是,我只收到一个值,即text1[ ]
All之间的总行数notes.json
。当然,这是因为将cat
所有文件的模式匹配一起输出。有没有办法输出每个notes.json
文件的行长度(从匹配模式返回) - 已排序?
答案1
- 不排序输出:
尝试对我自己的包含数千个 json 文件的文件树进行此操作:
$ find . -type f -name "*[0-9].json" \
-exec bash -c 'printf "%4d %s\n" $(jq ".bbx_basic[]" "$1" | wc -l) "$1"' bashscript {} ';'
[Example output in my tests]
130 ./Images/Training_set/00000845.json
13 ./Images/Training_set/00005869.json
13 ./Images/Training_set/00000991.json
26 ./Images/Training_set/00005631.json
1013 ./Images/Training_set/00001737.json
...
410 ./Annot_txt/Coco_en_2017/instances_val2017.json
0 ./Annot_txt/Coco_en_2017/instances_val2017.json
这将搜索限制为常规文件,以查找由我的模式指定的文件名*[0-9].json
。在您的情况下,您需要执行以下命令:
$ find . -type f -name "notes.json" \
-exec bash -c 'printf "%6d %s\n" $(jq ".text1[]" "$1" | wc -l) "$1"' bashscript {} ';'
- 排序输出:
- 修改后的命令将未排序的输出保存在中间临时文件(名为
outfile
)中,以防您想对其进行更多操作,而不仅仅是排序并发送到标准输出。/tmp/
如果需要,您可以在目录中找到该文件。 - 反向排序是在第一个(数字)字段上进行的,因此不应依赖于指定的区域设置。
find
当后台执行的作业退出时,排序就会开始,无论其退出状态是什么。
- 修改后的命令将未排序的输出保存在中间临时文件(名为
代码:
$ find . -type f -name "notes.json" \
-exec bash -c 'printf "%6d %s\n" $(jq ".text1[]" "$1" | wc -l) "$1" 2>/dev/null >> outfile' bashscript {} ';'; sort -k1,1nr outfile
通过以下方式,可以使上述内容同时变得更加健壮和灵活:
$ find . -type f -name "notes.json" -exec sh -c '
for file do
printf "%6d %s\n" $(jq ".text1[]" "$file" 2>/dev/null | wc -l) "$file"
done' sh {} + >> outfile; sort -k1,1nr outfile
结果是相同的,但根据 @StéphaneChazelas 的建议进行的改进包括:
sh
通过使用而不是使其更加便携bash
,- 通过对 的结果
find ...-exec sh -c '...'
采用批处理 (+
) 而不是逐文件处理 (\;
) 来最大程度地减少生成的 shell 数量,find
output
通过重定向整个输出来最小化文件描述符 ( ) 打开的数量,find
而不是像以前那样逐个文件进行重定向。
答案2
有任何逻辑推理说明为什么您需要它吗?人们可以将大量记录写入一行,因为不需要换行符。我宁愿说你选择了错误的武器来对付JSON。因此我建议使用PHP命令行界面,例如。以便计算 JSON 数组中的项目数。默认情况下,当前版本附带 JSON 文件格式的驱动程序。要使用的 PHP 函数是get_file_contents()
,json_decode()
和sizeof()
。
答案3
不幸的是,我无法为这一要求写一句话。下面的脚本解决了这个问题
#!/bin/bash
declare -a arr
arr=()
for i in $(find . -name notes.json)
do
arr+=`(echo $i | xargs cat | jq '.text1[]' | wc -l); echo $i; echo "\n"`
done
echo -e $arr | sort -nr > out.txt