linux 从查找中排除文件列表

pbwdgjma  于 2022-11-02  发布在  Linux
关注(0)|答案(8)|浏览(228)

如果我想在运行find时排除一个文本文件中的文件名列表,该如何操作呢?例如,我想执行以下操作:

find /dir -name "*.gz" -exclude_from skip_files

并获取/dir中除skip_files中列出的文件之外的所有.gz文件。但是find没有-exclude_from标志。我如何跳过skip_files中的所有文件?

2w3rbyxf

2w3rbyxf1#

我不认为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
zqry0prt

zqry0prt2#

这是我通常做的从结果中删除一些文件(在这种情况下,我寻找所有的文本文件,但不感兴趣的一堆valgrind memcheck报告,我们有在这里和那里):

find . -type f -name '*.txt' ! -name '*mem*.txt'

看起来很有效。

nzrxty8p

nzrxty8p3#

我觉得你可以试试

find /dir \( -name "*.gz" ! -name skip_file1 ! -name skip_file2 ...so on \)
0pizxfdo

0pizxfdo4#

find /var/www/test/ -type f \( -iname "*.*" ! -iname  "*.php" ! -iname "*.jpg" ! -iname "*.png"  \)

上面的命令给出了所有文件的列表,不包括扩展名为.php、.jpg和.png的文件。这个命令在putty中很有用。

cbeh67ev

cbeh67ev5#

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以获取详细信息。

xmq68pz9

xmq68pz96#

这个解决方案将检查所有文件(不完全排除在find命令之外),但会产生一个输出,跳过排除列表中的文件。我发现这在运行一个耗时的命令(file /dir -exec md5sum {} \;)时很有用。
1.您可以创建一个shell脚本来处理跳过逻辑并对找到的文件运行命令(使用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命令:

find /dir -name "*.gz" -exec ./skip_file.sh {} \;
ohfgkhjo

ohfgkhjo7#

这个答案是对another answer here的 * 概括 *。您不必列出每个文件名-假设您可以找到一个glob模式或正则表达式来定义要排除的一组文件。
语法如下所示-括号( & )必须转义:
查找/some/路径\(myregex \)...随便什么
例如,考虑一个包含大量文件的文件夹,这些文件的名称反映了创建它们的进程或守护程序的名称;例如temperature-records-furnaceA-20220729.gz

$ find . \( -iname "furnaceA" \)

进一步想象一下,我们还想包括furnaceA的文件,排除2019和2020的所有文件:

find . \( -iname "furnaceA" -not "2019" -not "2020" \)

任何你可以编写正则表达式的东西都是可能的,至少在GNU find中,表达式可以使用由-and-or表达式构造的 * 组合 * 逻辑来计算。

insrf1ej

insrf1ej8#

这应该可行:
skip_files
"健身“

  • 假设skip_files的每一行都有一个文件名,你可以通过$(<skip_files.txt)得到文件名列表。例如,echo $(<skip_files.txt)应该把它们都打印出来。
  • 对于每个文件名,您希望有一个! -path filename表达式。
  • 然后,将其与-name "*.gz"上的过滤器放在一起

相关问题