查找名称中至​​少包含三个字符的所有PDF


9

我想找到其名称(不包括扩展名)大于3的PDF文件。

$ find ~ -iregex ".{3,}/.pdf"

什么都不返回,但是

$ find ~ -iregex ".+/.pdf"

作品。

如何启用该{3,}变体?


什么长度 文件名长度?页面长度?
伊格纳西奥·巴斯克斯

Answers:


18

假设您使用的是GNU find(由于-iregexPOSIXfind的GNU扩展,所以您可能正在使用),-regex并且-iregex默认使用Emacs不识别的正则表达式{3,}。您需要使用-regextype选项指定其他类型的正则表达式。另外,您需要调整正则表达式以使其与完整路径匹配:

find ~ -regextype posix-extended -iregex '.*/[^/]{3,}.pdf'

您还应该对进行转义.,使其与“。”匹配 而不是任何字符:

find ~ -regextype posix-extended -iregex '.*/[^/]{3,}\.pdf'

因为我们只关心三个非“ /”字符,所以可以简化正则表达式:

find ~ -regextype posix-extended -iregex '.*[^/]{3}\.pdf'

为了完整起见,使用FreeBSD或NetBSD find(另一个支持-iregex,但不支持您的实现,.+如果没有,将无法正常运行-E),您应该编写:

find ~ -iregex '.*[^/]\{3\}\.pdf'

要么:

find -E ~ -iregex '.*[^/]{3}\.pdf'

没有-E,这是基本的正则表达式(如grep)和-E 扩展的正则表达式(如grep -E)。

使用ast-open的find

find ~ -iregex '.*[^/]{3}\.pdf'

(即开即用的扩展正则表达式)。


20

在这里,使用标准通配符会更容易:

find ~ -name '*???.[pP][dD][fF]'

或使用某些find实现(那些-regex也支持的实现-iname):

find ~ -iname '*???.pdf'

对于任意数量的字符而不是3,您可能希望将其恢复为-iregex可用的位置(请参阅@Stephen Kitt的答案),也可以使用zshksh93glob:

  • zsh

    set -o extendedglob # best in ~/.zshrc
    printf '%s\n' ~/**/?(#c3,).(#i)pdf(D)
    

    (与(D)一起考虑隐藏文件和隐藏目录中的文件find

    • (#cx,y)是正则zsh表达式的通配符{x,y}
    • (#i) 不区分大小写
    • ?任何单个字符的标准通配符(例如regexp .
    • **/:任意级别的子目录(包括0)
  • ksh93

    FIGNORE='@(.|..)' # to consider hidden files
    set -o globstar
    printf '%s\n' **/{3,}(?).~(i:pdf)
    
    • @(x|y):扩展的ksh通配符运算符,类似于regexp (x|y)
    • FIGNORE:特殊变量,用于控制全局文件忽略哪些文件。设置后,通常不会忽略隐藏文件,但是我们仍然希望忽略存在的...目录条目。
    • {x,y}(z)ksh93的正则表达式的等效z{x,y}
    • ~(i:...):不区分大小写的匹配。

Globs在find这里具有一些额外的优势,因为您可以获得一个排序列表(可以zsh使用oNglob限定符禁用该排序,或者使用其他排序标准),并且在文件名包含不构成有效字符的字节序列时(例如例如,在使用UTF-8字符集的语言环境中,该find方法将无法报告a $'St\xE9phane Chazelas - CV.pdf\xE9因为不是一个字符与regexp .或通配符?*GNU 都不匹配find


这对Bash有用吗?shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
wjandrea

7

我怎么知道它们是PDF?

除非你问,否则你不会。当然,我正在做书,但是您没有询问名称中带有的文件.pdf。仅由于文件名中包含字符.pdf不能使它成为PDF文件

实际上,让我们对此进行全面研究:如果文件名的最后四个字符为.pdf,则文件名中将始终有三个以上的字符

因此,以错误的方式执行此操作,您可能会说:

$ find . -type f -name "*???.pdf"
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Setup_MagicISO.exe.pdf

看到第二个吗?它实际上是一个可执行文件。(我知道,我改了名字。)而且我还缺少一个我可能宣誓就在文档目录中的PDF ...

$ ls Documents
McLaren 720s Coupe:Order Summary.pdf
Pioneer Premier DEH-P490IB CD Install Manual.PDF
Setup_MagicISO.exe.pdf

因此,使用-iname我们可以找到该文件,但这仍然是一个非PDF文件。

在这种情况下,我们真正想要做的就是使用命令检查文件的幻数file。一个选项输出MIME类型,它更易于解析。然后find查询变得简单-name "???*"

$ find . -type f -name "???*" -print0|xargs -0 file --mime
./.bash_history:                                              text/plain; charset=us-ascii
./.bash_logout:                                               text/plain; charset=us-ascii
./.bashrc:                                                    text/plain; charset=us-ascii
./.profile:                                                   text/plain; charset=us-ascii
./Documents/McLaren 720s Coupe:Order Summary.pdf:             application/pdf; charset=binary
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF: application/pdf; charset=binary
./Documents/Setup_MagicISO.exe.pdf:                           application/x-dosexec; charset=binary
./Downloads/Setup_MagicISO.exe:                               application/x-dosexec; charset=binary
./Downloads/WindowsUpdate.diagcab:                            application/vnd.ms-cab-compressed; charset=binary

让我们使用冒号分隔符,查找MIME type application/pdf,然后将该部分归零并打印结果。请注意,我的一个文件名称中带有一个冒号;所以我不能只是问awk ($2==":"){print $1}

$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF

现在,我们通过努力包括名为a和的PDF文件来完成工作abc

$ mkdir Documents/other
$ cp -a Documents/McLaren\ 720s\ Coupe\:Order\ Summary.pdf Documents/other/a
$ cp -a Documents/Pioneer\ Premier\ DEH-P490IB\ CD\ Install\ Manual.PDF  Documents/other/abc
$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF
./Documents/other/abc

就这样。我知道我可能会因令人讨厌的书呆子而感到生气,但是在我的工作中,有成千上万的NFS卷可供狩猎以及各种名称不佳的文件,我希望更多的人会被书呆子。

编辑添加:在现实世界中,我可能想利用它updatedb来构建可搜索的文件索引,locate而不是find读取该索引,而parallel不是xargs进行线程化。不过,这超出了这个问题的范围。我也是用笔直的脸写的。我为什么这么在乎呢?我可能正在寻找电影和音频文件;或某些类型的照片;或项目数据目录中的二进制可执行文件。


1
如果问询者的情况与您相同,其中PDF文件的名称不以结尾.pdf,那么您的学步将不胜感激。但这是一个相对不寻常的情况(尽管您的工作是这样),我们没有任何理由相信提问者实际上必须处理该问题,因此,我确实认为您提出的观点虽然有效,但会分散您的注意力-我认为您所说的有力方式将答案推到“(可能)无用”的境界。(当然,仅是我的意见。)
David Z

既然我们正在做书,那么您将如何处理PoC || GTFO多重 PDF之类的PDF ?
斯蒂芬·基特

@StephenKitt-不确定您要问什么,但我很感兴趣。在我看来,它们看起来像普通的PDF,但没有特别时髦的名称。这些会使我的建议解决方案失败吗?
Rich

@DavidZ我不确定该说些什么。我的意思是,当我已经说了很多话时,指出我正在做学步是不是有点学究?这就是为什么它没有“用处”的原因:找到PDF的好的解决方案应该是找到脚本,二进制可执行文件,库,媒体文件等的自适应解决方案。我什至无法开始看到如何适应其中的一种。 “压缩的Mach可执行文件”的其他答案,但我愿意学习。
Rich

1
@很多PDF都是ZIP文件,有些甚至是映像,甚至甚至是可启动的虚拟机...(请参阅前几期的“ spoilers”链接以获取提示;其余的都记录在PDF本身中。)
斯蒂芬·基特(Stephen Kitt)'18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.