AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 744432
Accepted
user2153235
user2153235
Asked: 2023-04-29 13:48:59 +0800 CST2023-04-29 13:48:59 +0800 CST 2023-04-29 13:48:59 +0800 CST

查找命令:排除特定文件夹中的文件模式

  • 772

我希望find命令排除一个文件夹中的某个文件模式,但不排除该文件夹的子文件夹。例如,如果我想排除subdir1/subdir1.1/UndesiredFiles*.tgz,以下将不起作用,因为星号匹配包括文件夹名称分隔符在内的连续字符/:

find * -not -path 'subdir1/subdir1.1/UndesiredFiles*.tgz'

以上排除了以下我不想排除的内容:

subdir1/subdir1.1/UndesiredFilesAndMore/*.tgz
subdir1/subdir1.1/UndesiredFilesAndMore/StillMore/*.tgz

我正在使用 Gnu find4.9.0 版。

find
  • 1 1 个回答
  • 94 Views

1 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2023-04-29T15:09:16+08:002023-04-29T15:09:16+08:00

    一些find实现支持一个谓词,除了它使用正则表达式(尽管其变体因实现和选项或其他谓词而异)而不是 shell glob 模式之外,它-regex是相同的。-path鉴于您find支持非标准 BSD 风格的-not谓词,它很可能是其中之一。

    LC_ALL=C find . ! -regex '\./subdir1/subdir1\.1/UndesiredFiles[^/]*\.tgz'
    

    我们将*glob 运算符(与 regexp 相同.*:0 个或更多字符)替换为 regexp [^/*](除 0 之外的 0 个或更多字符/)。

    正则表达式默认锚定,我们不需要显式的^or $。

    .与匹配任何字符的正则表达式运算符一样,我们需要将其转义(\.尽管[.]也可以)以使其.仅匹配文字(这很容易被忽略,因为.s 在文件名中很常见)。

    通常LC_ALL=C需要,除非您可以保证所有文件和目录名称仅由用户区域设置中的有效字符组成(这也适用于您的顺便说一句-path)。

    在 BSD 上,-regex采用标准的基本正则表达式,可以使用选项-E(如 forgrep或sed)将其更改为标准的扩展表达式。对于 GNU find,默认情况下,这是来自旧版 emacs 的正则表达式,但可以使用predicate更改-regextype为各种其他风格。在任何情况下,上面的特定正则表达式都适用于任何变体。


    对于find不支持的 s -regex,您可以执行以下操作:

    LC_ALL=C find . ! '(' -path './subdir1/subdir1.1/UndesiredFiles*.tgz' \
      ! -path './subdir1/subdir1.1/*/*' ')'
    

    那就是过滤掉./subdir1/subdir1.1/UndesiredFiles*.tgz那些*匹配的至少包括一个的除外/。

    或者您可以perl进行过滤:

    find . -exec printf '%s\0' {} + |
      perl -l -0ne 'print unless m{^\Q./subdir1/subdir1.1/UndesiredFiles\E[^/]*\.tgz\z}'
    

    在那里我们可以使用\Q...\Efor what's inside 被认为是一个固定的字符串,消除了对任何正则表达式运算符进行转义的需要。在这里,我们确实需要^在开始和\z结束时锚定正则表达式($在 perl 中,不是在末尾或在末尾的换行符之前匹配,因此会“错误地”排除文件$'UndesiredFiles.tgz\n')。

    (替换print为system "cmd", $_以路径作为参数运行命令)。

    一些(大多数)find实现-exec printf '%s\0' {} +可以替换为-print0. 一些实现支持带有or选项xargs的输出格式:-0-d '\0'

    find . -print0 |
      perl -0 -lne 'print unless m{^\Q./subdir1/subdir1\.1/UndesiredFiles\E[^/]*\.tgz\z}' |
      xargs -r0 cmd
    

    -l选项移到后面 -0,以便输出记录分隔符也可以是 NUL。


    如果使用zshshell,你不需要find,你可以这样做:

    set -o extendedglob
    print -rC1 -- **/*~subdir1/subdir1.1/UndesiredFiles[^/]#.tgz(ND)
    

    #regex 的 extendedglob 等价物在哪里*,~是except / and-not运算符,并且(ND)应用nullglob(如果没有匹配项则不扩展)和dotglob(包括隐藏文件)到那个 glob 扩展以 matchfind的行为。您还可以添加oN限定符以对列表N进行排序以进一步匹配的行为。ofind

    print -rC1 -- print列表r在1 C列上,但您当然可以使用另一个命令或循环遍历列表for。

    **/*(匹配任意数量的子目录中任意名称的文件,简称)如果您设置该选项,则(*/)#*可以缩写为。**globstarshort


    无论如何,请注意,虽然所有这些都排除了./subdir1/subdir1.1/UndesiredFiles-whatever.tgz,但它们不会排除./subdir1/subdir1.1/UndesiredFiles-whatever.tgz/other/file. 您需要调整模式或使用谓词-prune find来排除它们。

    • 5

相关问题

  • 如果未引用 -name 后面的模式,则 find 的奇怪行为

  • 将变量从子shell打印到父shell [重复]

  • 检查某个文件夹是否存在于某个目录中

  • 从命令行查找和替换 CSS 文件中的颜色

  • GNU find:在-exec中获取绝对和相对路径

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve