[英]Exclude list of files from find
如果我在运行find
时想要排除的文本文件中有一个文件名列表,我该怎么做? 例如,我想做类似的事情:
find /dir -name "*.gz" -exclude_from skip_files
并获取 /dir 中的所有 .gz 文件,skip_files 中列出的文件除外。 但是 find 没有-exclude_from
标志。 如何跳过skip_files
中的所有文件?
我认为find
没有这样的选项,您可以使用printf
和排除列表构建命令:
find /dir -name "*.gz" $(printf "! -name %s " $(cat skip_files))
这与执行以下操作相同:
find /dir -name "*.gz" ! -name first_skip ! -name second_skip .... etc
或者,您可以通过管道从find
进入grep
:
find /dir -name "*.gz" | grep -vFf skip_files
这是我通常从结果中删除一些文件的方法(在这种情况下,我查找了所有文本文件,但对我们到处都有的一堆 valgrind memcheck 报告不感兴趣):
find . -type f -name '*.txt' ! -name '*mem*.txt'
它似乎正在工作。
我想你可以试试
find /dir \( -name "*.gz" ! -name skip_file1 ! -name skip_file2 ...so on \)
find /var/www/test/ -type f \( -iname "*.*" ! -iname "*.php" ! -iname "*.jpg" ! -iname "*.png" \)
上面的命令给出了所有文件的列表,不包括扩展名为 .php、.jpg 和 .png 的文件。 这个命令在腻子中对我有用。
Josh Jolly 的 grep 解决方案有效,但复杂度为 O(N**2),对于长列表来说太慢了。 如果列表首先排序(O(N*log(N)) 复杂度),您可以使用comm
,它具有 O(N) 复杂度:
find /dir -name '*.gz' |sort >everything_sorted
sort skip_files >skip_files_sorted
comm -23 everything_sorted skip_files_sorted | xargs . . . etc
man
您计算机的comm
以获取详细信息。
此解决方案将遍历所有文件(不完全从find
命令中排除),但会从排除列表中生成跳过文件的输出。 我发现在运行耗时的命令( file /dir -exec md5sum {} \;
)时这很有用。
chmod
使其可执行,将echo
替换为其他命令): $ cat skip_file.sh
#!/bin/bash
found=$(grep "^$1$" files_to_skip.txt)
if [ -z "$found" ]; then
# run your command
echo $1
fi
创建一个包含要跳过的文件列表的文件,命名为files_to_skip.txt
(在您运行的目录上)。
然后使用 find 使用它:
find /dir -name "*.gz" -exec ./skip_file.sh {} \;
这个答案是对这里另一个答案的概括。 您不必列出每个文件名 - 假设您可以找到定义一组要排除的文件的 glob 模式或正则表达式。
语法是这样的——括号(
& )
必须被转义:
找到 /some/path \(myregex \)... 随便
例如,考虑一个包含大量文件的文件夹,这些文件的名称反映了创建它们的进程或守护进程的名称; 例如temperature-records-furnaceA-20220729.gz
:
$ find . \( -iname "furnaceA" \)
进一步想象,我们还想包含furnaceA
的文件,不包括 2019 年和 2020 年的所有文件:
find . \( -iname "furnaceA" -not "2019" -not "2020" \)
您可以为其编写正则表达式的任何内容都是可能的,并且至少在 GNU find
中,可以使用由-and
& -or
表达式构造的组合逻辑来评估表达式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.