如果我有一个文本文件中的文件名列表,我想排除当我运行 find,我如何做到这一点?例如,我想做这样的事情:
find
find /dir -name "*.gz" -exclude_from skip_files
然后把所有的。目录中的 gz 文件,但跳过 _ files 中列出的文件除外。但是 find 没有 -exclude_from标志。如何跳过 skip_files中的所有文件?
-exclude_from
skip_files
我觉得你可以试试
find /dir \( -name "*.gz" ! -name skip_file1 ! -name skip_file2 ...so on \)
我不认为 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
find /var/www/test/ -type f \( -iname "*.*" ! -iname "*.php" ! -iname "*.jpg" ! -iname "*.png" \)
上面的命令给出所有文件的列表,不包括。菲律宾。Jpg ang.Png 扩展。这个命令对我很管用。
这是我通常从结果中删除一些文件的方法(在这个例子中,我查找了所有的文本文件,但是对于我们这里和那里的一大堆 valGraduate memcheck 报告并不感兴趣) :
find . -type f -name '*.txt' ! -name '*mem*.txt'
好像起作用了。
Josh Jolly 的 grep 解决方案可以工作,但是具有 O (N * * 2)复杂性,因此对于长列表来说太慢了。如果首先对列表进行排序(O (N * log (N))复杂度) ,那么可以使用具有 O (N)复杂度的 comm:
comm
find /dir -name '*.gz' |sort >everything_sorted sort skip_files >skip_files_sorted comm -23 everything_sorted skip_files_sorted | xargs . . . etc
详细信息请参阅计算机的 comm。
这个解决方案将遍历所有文件(不完全排除 find命令) ,但是将从排除列表中生成一个输出跳过文件。 我发现在运行一个耗时的命令(file /dir -exec md5sum {} \;)时这很有用。
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的文件列表(在正在运行的目录中)。
files_to_skip.txt
然后使用 find:
find /dir -name "*.gz" -exec ./skip_file.sh {} \;
这个答案是从 概括到 另一个答案。您不必列出每个文件名——假设您可以找到定义要排除的一组文件的通用模式或正则表达式。
语法是这样的-括号 (和 )必须转义:
(
)
Find/some/path (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
这应该会奏效:
find * -name "*.gz" $(printf "! -path %s " $(<skip_files.txt))
健身
$(<skip_files.txt)
echo $(<skip_files.txt)
! -path filename
-name "*.gz"