概括:
- 一个给定的系统有很多带有名字的文本文件
~=
[type of file].[8-digit date]
。 - 要搜索这些文件,我喜欢(并希望保留)使用这个成语:(
find /path/ -name 'file.nnnn*' -print | xargs -e fgrep -nH -e 'text I seek'
其中nnnn
== 4 位数年份) - ......在过去的十年里,我也做
find
了很多年的球,比如find /path/ -name 'file.201[89]*' -print | xargs ...
- ...但现在我无法
find
在 2019 年和 2020 年使用find /path/ -name 'file.20{19,20}*' -print | xargs ...
- ......虽然那个“花括号通配符”(正确的术语?)适用于
ls
!
有没有一种{简洁、优雅}的方式来告诉find
我想要什么,而不是进行后期find
清理(即,我现在正在做什么)?
find /path/ -name 'file.*' -print | grep -e '\.2019\|\.2020' | xargs ...
? FWIW,我更喜欢与xargs
.
细节:
我在一个系统上工作,该系统的很多约定早在我之前,并且我无法更改。其中之一是,它有很多名称为 的文本文件~=
[type of file].[8-digit date]
,例如woohoo_log.20191230
. 在这些文件中搜索某些给定文本时,我通常(如几乎总是)使用find ... grep
成语(通常使用 Emacs' M-x find-grep
)。(FWIW,这是一个 Linux 系统
$ find --version
find (GNU findutils) 4.4.2
...
$ bash --version
GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)
如果我愿意,我目前缺乏改变其中任何一个的状态。)我经常有点知道手头问题的年份范围,因此会尝试限制find
返回的内容(以加快处理速度),例如)
find /path/ -type f -name 'file.nnnn*' -print | xargs -e fgrep -nH -e 'text I seek'
其中nnnn
== 4 位数年份。这个 WFM,我喜欢(并且想保留)使用上述成语......特别是因为我也可以用它来搜索多年
find /path/ -type f -name 'file.201[89]*' -print | xargs ...
但这个新的十年似乎打破了这个成语,而且(至少对我来说)最奇怪的是。(过去十年发生变化时我不在这里。)假设我选择了我知道在 2019 年的文件中的文本 && 2020 年的文件(例如,我可以打开文件并查看文本)。如果我现在这样做
find /path/ -name 'file.20{19,20}*' -print | xargs ...
grep
意外/令人讨厌地完成with no matches found
,因为
$ find /path/ -name 'file.20{19,20}*' -print | wc -l
0
但如果我这样做
find /path/ -type f -name 'file.*' -print | grep -e '\.2019\|\.2020' | xargs ...
grep
返回预期的结果。这很好,但是......嗯......这很丑陋,特别是因为这个“花括号 glob”(如果这个用法不正确或不推荐使用,请纠正我)从ls
!即,这向我显示了相关年份范围内的文件(即 2019..2020)
ls -al /path/file.20{19,20}*
因此我想知道:
- 我只是没有
find
为这个用例提供正确的 glob 吗?我需要告诉什么find
才能让它做ls
有能力/正确做的事情? - 这是一个问题
xargs
吗?如果是这样,我可以接受一个find ... -exec
解决方案,但是......我的大脑xargs
在 . (叫我弱智,但-exec
' 的语法让我的大脑受伤。)
使用
zsh
,您可以使用递归 globbing 及其<x-y>
匹配十进制数范围的 glob 运算符:(
(D)
也可以查看隐藏的(D
ot)目录find
;如果您不想要它们,大概可以省略它,并且-.
限制为在符号链接解析()之后识别的常规文件())。.
-
请注意,它也将匹配 on
file.00002020
(因为这是 2019 年和 2020 年之间的十进制数),并且在您的方法中file.20201234
就像它file.2020
which matchesfile.<2019-2020>
后跟1234
which matches一样*
。执行此操作的标准(POSIX
sh
和实用程序)方法是:(其中添加
/dev/null
使您获得与 GNU 相同的效果grep
以-H
强制显示文件名)请注意, 的输出
find -print
与 的预期输入格式不兼容xargs
。使用 GNU 实用程序,您可以使用find -print0
andxargs -r0
,但这不是必需的,因为find -exec ... {} +
具有相同的行为,更短且更便携。在
ls -al /path/file.20{19,20}*
中,它ls
与 没有任何关系{19,20}*
。在该命令中,shell 执行大括号扩展和通配符,/path/file.20{19,20}*
因为它没有被引用:在
find /path/ -name 'file.20{19,20}*'
,'file.20{19,20}*'
中被引用,所以 shell 不理会它,find
然后应用它自己的模式匹配规则,不支持大括号扩展。这里引用GNUfind
手册:如果您真的想使用大括号扩展来递归搜索目录,在 bash 中,您可以启用递归通配符 (
globstar
) (并可能dotglob
像查看隐藏目录一样find
),并使用printf
withxargs
:或者,您可以使用
find
with-regex
而不是-name
一些实现所支持的find
。使用 GNUfind
:这不是您问题的一般案例答案,但可能有一种简单的方法可以做到这一点,具体取决于您拥有多少文件历史记录。在九月/十月寻找东西时,我经常遇到类似的情况。一个简单的解决方法是使用这样的 a 模式:
它不完全相同,因为除了 2019 年和 2020 年之外,它还将匹配 2010 年和 2029 年。大概您还没有任何日期为 2029 年的文件。如果您的存档不能追溯到 2010 年,那么这应该是功能性的相等的。