如何将find命令转换为改为使用grep过滤,然后在输出中使用`exec`命令?

时间:2019-09-01 15:43:43

标签: bash shell grep find

我有一个场景,我需要在找到的每个文件上执行一系列命令。这通常会很好用,除非我有100多个文件和文件夹要从find的执行结果中排除。直接从外壳变得笨拙且不可执行。似乎最好使用类似于targrep允许此类文件的“排除文件”。

由于find不接受排除文件,但是grep接受,我想知道:如何将以下内容转换为可替换排除的命令(prune )和exec中的find函数,将 grep 与排除文件(grep -v -f excludefile)结合使用来排除文件夹和文件,然后执行结果上的一系列命令,就像当前命令一样:

find $IN_PATH -regextype posix-extended \
  -regex "/(excluded1|excluded2|excluded3|...|excludedN)" -prune \
  -o -type f \
  -exec sh -c "( cmd -with_args 1 '{}'; cmd -args2 '{}'; cmd3 '{}') \
    | cmd4 | cmd5 | cmd6; cmd7 '{}'" \; \
  > output

作为旁注(不是很重要),我读到如果不使用exec,此过程的效率将大大降低,并且每次运行该过程都将花费100多分钟的时间来执行,因此我不想将其降低到不必要的程度。

2 个答案:

答案 0 :(得分:1)

我认为要实现您的方案的最好方法是将单行代码分成两行,并引入带有parallel的xargs。

find $IN_PATH -regextype posix-extended \
  -regex "/(excluded1|excluded2|excluded3|...|excludedN)" -prune \
  -o -type f  > /tmp/full_file_list
cat /tmp/full_file_list|grep -f excludefile |xargs -0 -n 1 -P <nr_procs> sh -c 'command here' >output

请参阅Bash script processing limited number of commands in parallelDoing parallel processing in bash?,以了解有关bash中并行的更多信息

对文件的查找和命令在一个衬套中面临disk-io冲突,溢出一个衬套可能会加快处理速度,

提示:请记住将full_file_list / excludefile / output放入排除规则中,并始终在较小的目录上调试命令以减少等待时间

答案 1 :(得分:0)

为什么不简单:

find . -type f |
grep -v -f excludefile |
xargs whatever

关于this process is already consuming over 100 minutes to execute-无论您使用什么命令行替换上面的whatever,这几乎肯定是一个问题,如果您发布一个单独的问题,我们可能会帮助您改善这一问题。