使 `xargs` 使用 N 个参数的最大倍数

使 `xargs` 使用 N 个参数的最大倍数

我有一个包含十万多个ID的文件。每个ID由8~16位十六进制数字组成:

178540899f7b40a3
6c56068d
8c45235e9c
8440809982cc
6cb8fef5e5
7aefb0a014a448f
8c47b72e1f824b
ca4e88bec
...

我需要在包含周围的目录树中找到相关文件2×10 9文件。

给定一个像 的 ID 6c56068d219144dd,我可以通过以下方式找到其相应的文件:

find /dir -type f -name '* 6[cC]56068[dD]219144[dD][dD] *'

但这至少需要两天才能完成......

我想做的是尽可能find多地打电话给-o -iname GLOB三胞胎ARG_MAX

这是我想做的事情:

sed -e 's/.*/-o -iname "* & *"' ids.txt |
xargs find /dir -type f -name .

我的问题是我不能强迫xargs只接受完整的三胞胎。

我该怎么做?

答案1

这是错误的方法,如果重点是查找名称具有这些 ID 之一作为其空格分隔单词之一的所有文件,那么您可以这样做:

find /dir -type f -print0 |
  gawk '
    !ids_processed {ids[$0]; next}
    {
      n = split(tolower($NF), words, " ")
      for (i = 1; i <= n; i++)
        if (words[i] in ids) {
          print
          break
        }
    }' ids.txt ids_processed=1 RS='\0' FS=/ -

然后,您仅处理文件列表一次,查找 100k id 只是在哈希表中查找,而不是执行最多 100k 正则表达式/通配符匹配。

答案2

我会做什么:

编写一个脚本将所有文件名保存到临时文件中:

# maybe run this from cron or behind inotifywait
find dir -type f -print > /tmp/filelist

然后根据需要使用输入文件进行查找:

fgrep -if hexids /tmp/filelist 

我可能建议使用-wif代替,-if但从其他评论来看,尚不清楚您在问题中提供了准确的信息。man grep了解更多信息。

答案3

感谢@Kusalananda,我想到了一个可能的解决方案:

第一步是使 的每个-a -b X三元组被视为单个参数xargs。然后,您在内联脚本中重新拆分这些单参数三元组sh并调用其中的实用程序。

... |
awk '{ printf("%s%c", $0, 0) }' |
xargs -0 sh -c '[ "$#" -gt 0 ] && { printf %s\\n "$@" | xargs "$0" }' my_command

相关内容