如果我想在运行find时排除一个文本文件中的文件名列表,该如何操作呢?例如,我想执行以下操作:
find
find /dir -name "*.gz" -exclude_from skip_files
并获取/dir中除skip_files中列出的文件之外的所有.gz文件。但是find没有-exclude_from标志。我如何跳过skip_files中的所有文件?
-exclude_from
skip_files
2w3rbyxf1#
我不认为find有这样的选项,你可以使用printf和你的排除列表来构建一个命令:
printf
find /dir -name "*.gz" $(printf "! -name %s " $(cat skip_files))
这与执行以下操作相同:
find /dir -name "*.gz" ! -name first_skip ! -name second_skip .... etc
或者,您可以从find以管道方式连接到grep:
grep
find /dir -name "*.gz" | grep -vFf skip_files
zqry0prt2#
这是我通常做的从结果中删除一些文件(在这种情况下,我寻找所有的文本文件,但不感兴趣的一堆valgrind memcheck报告,我们有在这里和那里):
find . -type f -name '*.txt' ! -name '*mem*.txt'
看起来很有效。
nzrxty8p3#
我觉得你可以试试
find /dir \( -name "*.gz" ! -name skip_file1 ! -name skip_file2 ...so on \)
0pizxfdo4#
find /var/www/test/ -type f \( -iname "*.*" ! -iname "*.php" ! -iname "*.jpg" ! -iname "*.png" \)
上面的命令给出了所有文件的列表,不包括扩展名为.php、.jpg和.png的文件。这个命令在putty中很有用。
cbeh67ev5#
Josh Jolly的grep解决方案是可行的,但是复杂度为O(N**2),这使得它对于长列表来说太慢了。如果列表先排序(复杂度为O(N*log(N))),那么可以使用comm,它的复杂度为O(N):
comm
find /dir -name '*.gz' |sort >everything_sorted sort skip_files >skip_files_sorted comm -23 everything_sorted skip_files_sorted | xargs . . . etc
man您计算机的comm以获取详细信息。
man
xmq68pz96#
这个解决方案将检查所有文件(不完全排除在find命令之外),但会产生一个输出,跳过排除列表中的文件。我发现这在运行一个耗时的命令(file /dir -exec md5sum {} \;)时很有用。1.您可以创建一个shell脚本来处理跳过逻辑并对找到的文件运行命令(使用chmod使其可执行,使用其他命令替换echo):
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
1.创建一个名为files_to_skip.txt的文件,其中包含要跳过的文件的列表(在您运行的目录中)。1.然后使用find命令:
files_to_skip.txt
find /dir -name "*.gz" -exec ./skip_file.sh {} \;
ohfgkhjo7#
这个答案是对another answer here的 * 概括 *。您不必列出每个文件名-假设您可以找到一个glob模式或正则表达式来定义要排除的一组文件。语法如下所示-括号( & )必须转义:查找/some/路径\(myregex \)...随便什么例如,考虑一个包含大量文件的文件夹,这些文件的名称反映了创建它们的进程或守护程序的名称;例如temperature-records-furnaceA-20220729.gz:
(
)
temperature-records-furnaceA-20220729.gz
$ find . \( -iname "furnaceA" \)
进一步想象一下,我们还想包括furnaceA的文件,排除2019和2020的所有文件:
furnaceA
find . \( -iname "furnaceA" -not "2019" -not "2020" \)
任何你可以编写正则表达式的东西都是可能的,至少在GNU find中,表达式可以使用由-and和-or表达式构造的 * 组合 * 逻辑来计算。
-and
-or
insrf1ej8#
这应该可行:skip_files"健身“
$(<skip_files.txt)
echo $(<skip_files.txt)
! -path filename
-name "*.gz"
8条答案
按热度按时间2w3rbyxf1#
我不认为
find
有这样的选项,你可以使用printf
和你的排除列表来构建一个命令:这与执行以下操作相同:
或者,您可以从
find
以管道方式连接到grep
:zqry0prt2#
这是我通常做的从结果中删除一些文件(在这种情况下,我寻找所有的文本文件,但不感兴趣的一堆valgrind memcheck报告,我们有在这里和那里):
看起来很有效。
nzrxty8p3#
我觉得你可以试试
0pizxfdo4#
上面的命令给出了所有文件的列表,不包括扩展名为.php、.jpg和.png的文件。这个命令在putty中很有用。
cbeh67ev5#
Josh Jolly的grep解决方案是可行的,但是复杂度为O(N**2),这使得它对于长列表来说太慢了。如果列表先排序(复杂度为O(N*log(N))),那么可以使用
comm
,它的复杂度为O(N):man
您计算机的comm
以获取详细信息。xmq68pz96#
这个解决方案将检查所有文件(不完全排除在
find
命令之外),但会产生一个输出,跳过排除列表中的文件。我发现这在运行一个耗时的命令(file /dir -exec md5sum {} \;
)时很有用。1.您可以创建一个shell脚本来处理跳过逻辑并对找到的文件运行命令(使用
chmod
使其可执行,使用其他命令替换echo
):1.创建一个名为
files_to_skip.txt
的文件,其中包含要跳过的文件的列表(在您运行的目录中)。1.然后使用find命令:
ohfgkhjo7#
这个答案是对another answer here的 * 概括 *。您不必列出每个文件名-假设您可以找到一个glob模式或正则表达式来定义要排除的一组文件。
语法如下所示-括号
(
&)
必须转义:查找/some/路径\(myregex \)...随便什么
例如,考虑一个包含大量文件的文件夹,这些文件的名称反映了创建它们的进程或守护程序的名称;例如
temperature-records-furnaceA-20220729.gz
:进一步想象一下,我们还想包括
furnaceA
的文件,排除2019和2020的所有文件:任何你可以编写正则表达式的东西都是可能的,至少在GNU
find
中,表达式可以使用由-and
和-or
表达式构造的 * 组合 * 逻辑来计算。insrf1ej8#
这应该可行:
skip_files
"健身“
skip_files
的每一行都有一个文件名,你可以通过$(<skip_files.txt)
得到文件名列表。例如,echo $(<skip_files.txt)
应该把它们都打印出来。! -path filename
表达式。-name "*.gz"
上的过滤器放在一起