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 / 问题 / 569541
Accepted
SebMa
SebMa
Asked: 2020-02-25 21:40:39 +0800 CST2020-02-25 21:40:39 +0800 CST 2020-02-25 21:40:39 +0800 CST

find 没有成功排除特定目录

  • 772

我想仅.git/使用命令列出除目录内的所有文件之外的所有文件find。

我试过这个:

$ find . -path .git -prune -type f
$

它返回了 0 个文件(而不是我拥有的 2 个文件)所以我尝试了这个:

$  find . -not -path .git -type f | grep -c '\.git'
1770
$

我不明白为什么这些都不起作用,你能帮忙吗?

EDIT0:感谢@icarus,我看到路径必须在前面,./因此我错过了OR运算符,这个命令有效:

$ find . -path ./.git -prune -o -type f | grep '\.git'
./.git
./.gitignore
$

EDIT1: 为什么其他命令不起作用?

$ find . -not -path ./.git -a -type f | grep -c '\.git'
1770
$

EDIT2:最后一个问题:为什么-prune谓词不需要在下面的命令中-o -print打印./.git和结果:./.gitignore

$ find . -name ".git*" -prune | grep git
./.git
./.gitignore
$ find . -name ".git*" -prune -o -print | grep -c git
0

EDIT3:谢谢@rastafile:

$ find . -name ".git*" -prune | grep git
./.git
./.gitignore
$ find . -name ".git*" -prune -print | grep git
./.git
./.gitignore
$ find . -name ".git*" -prune -o -print | grep git
$

当前面的表达式为 true 时,GNU 似乎隐式地查找-prune谓词调用:-print

如果表达式不包含除 -prune 之外的任何操作,则对表达式为真的所有文件执行 -print。

总之:我需要的命令是:

$ find . -name ".git*" -prune -o -type f -print

谢谢大家。

find
  • 2 2 个回答
  • 236 Views

2 个回答

  • Voted
  1. icarus
    2020-02-25T22:09:57+08:002020-02-25T22:09:57+08:00

    在 find 中加入术语的默认操作是and这样

    find / -user root -name fred
    

    表示查找既属于 root 又称为 fred 的文件。你想做一个or操作,如果它叫做“.git”然后修剪它或者如果它是一个文件然后列出它。

    find . \( -name .git -prune \) -o -type f
    

    注意我使用的是-name而不是-path. 如果你给它一个起始位置,.那么.git顶层目录将被调用./.git以用于-path.

    所以

    find . -path .git -prune -type f
    

    -path .git什么都不提供,因为所有文件都开始时没有匹配项./

    find . -not -path .git -type f
    

    为您提供每个文件,因为所有内容都匹配-not -path .git,因此唯一的过滤是-type f将输出限制为文件。

    • 2
  2. Best Answer
    user373503
    2020-02-26T13:11:10+08:002020-02-26T13:11:10+08:00

    -path和之间有很大的不同-name——它们根本不相似:“名称”只看最后一部分,“路径”看整个斜杠链。“文件名”应该是什么意思,或者“路径名”,总是有点争议。但这里很清楚也很重要。

    这有效(你说):

    find . -path ./.git -prune -o -type f 
    

    您从 开始.,因此会找到并修剪默认的 gitdir。不./.git存在其他人,因此检查其他所有人 ( -o) 的类型文件。


    你的最后一个例子:

    find . -not -path ./.git -a -type f 
    

    不起作用,它只会找到所有文件。

    如果你想避免-prune,你必须匹配里面的每个条目:

    -path './.git/*'
    

    我同意 Icarus 的 -name/-prune 组合,但我有一个修改:

    ]# find . -name .git -prune -o -type f -name '*git*' -print   
    ./.git.filehidd
    ./gitfile
    

    这里不需要括号。

    即使-name '*git*'添加,用于测试/减少输出。

    最后的显式操作-print通过 prune 抑制打印:

    ]# find . -name .git -prune                                 
    ./.git
    ./10/.git
    

    我不确定括号;我查了一下man find(GNU),发现了关于它们的很好的细节:

     find . -name .snapshot -prune -o \( \! -name *~ -print0 \)
    

    ...,但省略了名为 .snapshot 的文件和目录(以及其中的任何内容)。它还省略了名称以 ~ 结尾的文件或目录,但不省略其内容。 构造-prune -o \( ... -print0 \) 很常见。 这里的想法是 -prune 之前的表达式匹配要修剪的东西。但是,-prune 操作本身返回 true,因此以下 -o 确保仅对那些没有被修剪的目录评估右侧(修剪目录的内容甚至没有被访问,因此它们的内容无关紧要)。-o 右侧的表达式放在括号中只是为了清楚起见. 它强调 -print0 操作仅发生在没有应用 -prune 的事物上。因为测试之间的默认 `and' 条件比 -o 绑定得更紧密,所以无论如何这都是默认值,但括号有助于显示正在发生的事情。

    对我来说,更清楚的是:

    find . ( -name .snapshot -prune ) -o ( ! -name '*~' -print0 )
    

    但是这样是行不通的!

    如果你在-a这里省略了类似的东西,那么-o就足够突出了,所以可以省略括号,也是为了清楚起见。


    (因为 shell 也喜欢括号,所以你必须引用它们。但是再见了。)

    1) find . -name .snapshot -prune -o \( \! -name *~ -print0 \)
    
    2) find . -name .snapshot -prune -o ! -name '*~' -print0 
    

    不带引号的!可以工作(我的可以),不带引号的*不行。


    因此,要查找除任何目录之外的文件(所有类型).git:

    find -name '.git' -type d -prune -o -print 
    

    (类型 -d 也可以省略,如果您不在乎...请参阅 Kamil 的评论...那里是一片丛林,而 find 是一种小型编程语言:您需要什么)

    • 1

相关问题

  • 如果未引用 -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