【问题标题】:gnu find: apply -regex on basename onlygnu find:仅对基本名称应用-regex
【发布时间】:2012-05-04 18:20:38
【问题描述】:

我想搜索基本名称与正则表达式匹配的文件。我试过这个:

$ find  '/my/path' -regextype posix-extended -regex 'reg1' -regex 'reg2'

我的问题是正则表达式针对完整路径进行了测试。我只想测试文件的基本名称。

【问题讨论】:

    标签: regex linux find command


    【解决方案1】:

    您需要锚定正则表达式,例如

    find /my/path -regextype posix-extended -regex 'mumble$'
    

    其中mumble 必须以排除/ 字符的方式书写(例如,您不能使用.*,您需要说[^/]*)。

    【讨论】:

    • 是的,但是...我的命令是由程序生成的,我不控制正则表达式。
    • 实际上,这个解决方案匹配任何以“mumble”结尾的文件名,例如,/my/path/we_mumble
    • 另外,-regex 必须匹配完整路径,所以它有一个隐含的^...$
    【解决方案2】:

    GNU find 不包括任何仅适用于基本名称的正则表达式运算符。这是不幸的。我们最接近的方法是修改正则表达式以从正则表达式的前面去除斜线分隔的部分:

    find /my/path -regextype posix-extended -regex ".*/reg1"
    

    这适用于普通的 linux 路径名,但对于带有不寻常字符(例如换行符)的路径名可能会失败。

    正如 geekosaur 所指出的,您的输入正则表达式不应匹配多个组件。如果您对正则表达式没有任何控制权(例如,如果它作为变量 $REG1 传递),您可以尝试修改它以将 . 转换为 [^/]

    find /my/path -regextype posix-extended -regex ".*/${REG1/./[^/]}"
    

    这对于很多正则表达式都会失败(例如,'.*.txt' 会被严重损坏)。但是,如果您知道正则表达式会很简单,那么它可能会起作用。

    对于较慢但有效的解决方案,您可以在 -exec 块内进行所有模式匹配:

    find /my/path -exec bash -c 'basename "$0" | egrep -q '"'$REG1'"' && echo "$0"' '{}' ';'
    

    这里的逻辑是find 枚举所有文件并将它们分配给子shell 中的$0。子shell 使用basenameegrep 将输出过滤到与输入正则表达式匹配的路径。请注意 egrep 查找本地匹配项;如果要匹配完整的基本名称,请使用egrep -q '"'^$REG1\$'"'

    根据输入正则表达式的语义(例如,如果$REG1 旨在匹配基本名称的任何子字符串),首先在整个路径中搜索正则表达式然后过滤到仅基本名称:

    find /my/path -regextype posix-extended -regex ".*${REG1}.*" \
        -exec bash -c 'basename "$0" | egrep -q '"'$REG1'"' && echo "$0"' '{}' ';'
    

    【讨论】:

      猜你喜欢
      • 2023-02-02
      • 2011-05-15
      • 1970-01-01
      • 2020-02-14
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      相关资源
      最近更新 更多