有没有办法可以使用 xargs 一次处理多个命令的组合输出?

有没有办法可以使用 xargs 一次处理多个命令的组合输出?

我有多个 shell 命令,我想将它们传输到同一个xargs实例中,以便可以一起处理它们。

我有两个输入,一个文件和一个全局表达式:

$ cat subdomains.txt 

admin.site.com
web.site.com
api.site.com

$ ls -d x*

xab  xac  xad

我想把它变成这样:

admin.site.com:xab
admin.site.com:xac
admin.site.com:xad
web.site.com:xab
web.site.com:xac
web.site.com:xad
api.site.com:xab
api.site.com:xac
api.site.com:xad

这是我尝试过的命令(不起作用):

cat subdomains.txt |  ls -d x* | xargs -I value1,value2 echo 'value1:value2'

答案1

你可以用 GNU 来做到这一点parallel

$ printf '%s\n' x* | parallel echo "{1}:{2}" :::: subdomains.txt :::: -
admin.site.com:xab
admin.site.com:xac
admin.site.com:xad
web.site.com:xab
web.site.com:xac
web.site.com:xad
api.site.com:xab
api.site.com:xac
api.site.com:xad

答案2

需要一个丑陋的方法:eval因为大括号扩展通常发生在变量扩展之前,所以我们需要两轮评估。

sub=$( paste -sd, subdomains.txt )
xs=$( ls -d x* | paste -sd, )
eval "printf '%s\n' {$sub}:{$xs}"

更好:将每个单独步骤的结果存储在数组中,然后使用嵌套循环来组合它们。

mapfile -t sub < subdomains.txt
xs=( x* )
for s in "${sub[@]}"; do
  for x in "${xs[@]}"; do
    echo "$s:$x"
  done
done

答案3

$ printf '%s\n' x* | join -t : -1 2 -2 2 -o 1.1,2.1 subdomains.txt -
admin.site.com:xaa
admin.site.com:xab
admin.site.com:xac
web.site.com:xaa
web.site.com:xab
web.site.com:xac
api.site.com:xaa
api.site.com:xab
api.site.com:xac

这用于在文件中列出的域和以当前目录中的字符开头的文件名join之间生成某种叉积。subdomains.txtx

叉积是通过要求join在不存在的字段(第 2 列,用-1 2和指定-2 2)上连接两个数据集来生成的。我们还将输入和输出字段分隔符指定为:with -t :,并且我们明确要求使用使用从每个文件中获取第一列-o 1.1,2.1(否则我们将在结果中得到一个空的第一列)。

答案4

printf '%s\n' x*仅当您的文件超过 32000 个时才需要。

否则这将起作用:

parallel mytool.sh --parm1 {1} --parm2 {2} :::: subdomains.txt ::: x*

阅读第 1+2 章http://www.lulu.com/shop/ole-tange/gnu-parallel-2018/paperback/product-23558902.html(可以在以下位置下载https://doi.org/10.5281/zenodo.1146014)。您的命令行会因此而喜欢您。

(如果x*文件来自split您还应该阅读第 9 章

parallel -a bigfile --block 10M --pipepart --argsep ,, -I ,, parallel --pipe --tee wc {} ::: -l -c -w

)。

相关内容