Shell 循环浏览sh中具有特定MIME类型的文件列表

Shell 循环浏览sh中具有特定MIME类型的文件列表,shell,sh,dash-shell,Shell,Sh,Dash Shell,我有一个目录,需要获得一个包含MIME类型application/pdf的文件列表,我可以使用CompressPdf函数循环并处理这些文件。剩下的文件只需要使用cp在目标目录上复制,我还需要一个循环列表 明显的障碍是使用NUL正确处理UNIX文件名。到目前为止,我已经想到了这个: find "dir-to-search" -type f -print0 | xargs -0 file -0 --mime-type -F " " | grep -zZ "application/pdf" 但是gr

我有一个目录,需要获得一个包含MIME类型application/pdf的文件列表,我可以使用CompressPdf函数循环并处理这些文件。剩下的文件只需要使用cp在目标目录上复制,我还需要一个循环列表

明显的障碍是使用NUL正确处理UNIX文件名。到目前为止,我已经想到了这个:

find "dir-to-search" -type f -print0 | xargs -0 file -0 --mime-type -F " " | grep -zZ "application/pdf"
但是grep不能正确处理结果,因为file-0在文件名后面插入NUL,在MIME信息后面插入\n。它将返回如下内容:

0000000   .   /   f   i   l   e   1   .   p   d   f  \0                                                                                                                                                                                                      
0000010   a   p   p   l   i   c   a   t   i   o   n   /   p   d   f  \n                                                                                                                                                                                      
0000020   .   /   f   i   l   e   2   .   p   d   f  \0                                                                                                                                                                                                      
0000030   a   p   p   l   i   c   a   t   i   o   n   /   p   d   f  \n
另一个障碍是将所有内容放在一行限制了在每次迭代中使用几行代码的能力。调用xargs-I{}sh-c{}内联将生成一个新进程,该进程无法调用我的CompressPdf函数。我正在使用破折号和导出-f压缩PDF不工作。递归执行$0是我的最佳选择

目前,我的代码在递归地同时处理单个目录中的多个PDF文件时运行良好。但是,它阻止我一次处理大量文件

有人能帮我吗?我试图用Dash而不是Bash来编写,以获得更高的性能,尽管数组不可用。如果没有其他方法,我可以切换到Bash。

尝试以下方法:

find . -type f -print0 |
xargs -0 file -0 -0 --mime-type |
sed -z 'N;/\x00application\/pdf$/s///p'
因此,首先从:

-0,-print0

如果此选项重复多次,则打印文件 只需文件名,后跟NUL,后跟说明 或错误:文本后跟每个条目的第二个NUL

因此,请指定它两次

然后我使用sed-z一次读取两行零分隔流-z是sed的gnu扩展。如果两个零分隔行以application/pdf结尾,则删除此匹配字符串并打印文件名

您始终可以使用xxd处理以零结尾的字符串:


已找到应用程序/pdf的MIME类型-名称“*.pdf”还不够?@KamilCuk我以前想过,但决定使用MIME类型而不是文件扩展名。这样就可以有一点自由使用任何扩展,甚至没有扩展。虽然我非常怀疑有人曾经使用其他扩展名来处理PDF文件。@oguzismail通过一个接一个的管道命令,但我想我最终会得到一个由xargs-I{}sh-c{}处理的stdin。对于列表中的每个文件,在实际压缩之前,我想做一些其他的事情,比如条件检查。子sh进程不能从父进程调用函数。export-f在短划线中不起作用。@oguzismail我依赖于xargs-P的进程池功能。使用find-exec,所有文件都将一次处理,这不是我所期望的。第二个带有xxd的代码段可以工作,但第一个代码段打印出重复的文件名,例如:file1.pdf\0file1.pdf\0。你能编辑它吗?sed命令和脚本太复杂了,我很难在短时间内理解。
find . -type f -print0 |
xargs -0 file -0 -0 --mime-type |
# convert to hex
xxd -p -c1 | tr '\n' ' ' | sed 's/00 /\n/g' |
# have filename and mime type on a single line
sed 'N;s/\n/00 /' |
# this is actually grep
# grep for application/pdf in hex
sed -n '/ 00 '"$(echo -n 'application/pdf' | xxd -p | tr -d '\n' | sed -r 's/(..)/\1\n/g' | paste -sd' ')"'/s// 00/p' |
# reverse the stream from hex to ascii
xxd -r -p