【发布时间】:2014-04-28 18:57:37
【问题描述】:
如果我在运行find 时想要排除文本文件中的文件名列表,我该怎么做?例如,我想做这样的事情:
find /dir -name "*.gz" -exclude_from skip_files
并获取 /dir 中的所有 .gz 文件,skip_files 中列出的文件除外。但是 find 没有 -exclude_from 标志。如何跳过skip_files中的所有文件?
【问题讨论】:
如果我在运行find 时想要排除文本文件中的文件名列表,我该怎么做?例如,我想做这样的事情:
find /dir -name "*.gz" -exclude_from skip_files
并获取 /dir 中的所有 .gz 文件,skip_files 中列出的文件除外。但是 find 没有 -exclude_from 标志。如何跳过skip_files中的所有文件?
【问题讨论】:
我觉得你可以试试
find /dir \( -name "*.gz" ! -name skip_file1 ! -name skip_file2 ...so on \)
【讨论】:
我认为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
【讨论】:
included_paths=("./.aws/*" "./.bash_env.m4") && find . -type f -name '*.m4' \( -path "${included_paths[0]}" $(printf " -or -path '%s'" "${included_paths[@]:1}") \)。当我直接将路径放入 find 命令时,它确实有效。
-vw 匹配整行
find /var/www/test/ -type f \( -iname "*.*" ! -iname "*.php" ! -iname "*.jpg" ! -iname "*.png" \)
上面的命令给出了所有文件的列表,不包括扩展名为 .php、.jpg 和 .png 的文件。这个命令在腻子中对我有用。
【讨论】:
这是我通常会从结果中删除一些文件的方法(在这种情况下,我查找了所有文本文件,但对我们到处都有的一堆 valgrind memcheck 报告不感兴趣):
find . -type f -name '*.txt' ! -name '*mem*.txt'
它似乎正在工作。
【讨论】:
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 {} \;
【讨论】: