如何在 xargs 中获取行号?

如何在 xargs 中获取行号?

我想将一些文件并行上传到机器。这里有一个主机列表和一个应按索引上传的文件列表:1.txtgoes to hostOne2.txtgoes tohostTwo等。以下是我尝试执行的操作:

cat hosts | xargs -P 10 -I {} scp ./${LINE}.txt user@{}:/tmp

如何使其工作(${LINE}不是 xargs 语法的一部分)?

答案1

此过滤器

awk '{print NR ".txt user@" $1 ":/tmp"}'

变成foo1.txt user@foo:/tmp数字随着每行增加。您的命令应类似于:

<hosts awk '{print NR ".txt user@" $1 ":/tmp"}' | xargs -L 1 scp

根据您的需要进行调整(例如-P 10)。另请注意,您不需要cat读取该文件。

答案2

xargs无法为您解释行号。相反,您应该使用类似以下方法nl添加行号:

$ echo -ne "a\nb\nc\n" \
    | nl -bt -nln
1       a
2       b
3       c

然后,您需要格式化该命令,以便可以将其xargs作为参数传递给scp,使用类似以下命令sed

$ echo -ne "a\nb\nc\n" \
    | nl -bt -nln \
    | sed -re 's!^([0-9]+) +\t(.+)$!./\1.txt user@\2:/tmp!'
./1.txt user@a:/tmp
./2.txt user@b:/tmp
./3.txt user@c:/tmp

最后,跑吧!

$ echo -ne "a\nb\nc\n" \
    | nl -bt -nln \
    | sed -re 's!^([0-9]+) +\t(.+)$!./\1.txt user@\2:/tmp!' \
    | xargs -P10 -l1 -t scp
scp ./1.txt user@a:/tmp
scp ./2.txt user@b:/tmp
scp ./3.txt user@c:/tmp

请注意,这会导致主机和传输的文件之间的关联较差(仅通过行号完成......)

nl

  • -bt- 仅限非空行
  • -nln- 使用左对齐编号,不带前导零

sed

  • -r- 使用扩展的正则表达式
  • -e 's!^([0-9]+) +\t(.+)$!./\1.txt user@\2:/tmp!'- 要使用的脚本
    • ^([0-9]+) +\t(.+)$匹配数字,然后是空格,然后是制表符,然后任意字符
    • \1.txt user@\2:/tmp- 替换,使用上面的组(内部()

xargs

  • -P10- 同时运行最多 10 个进程
  • -l1- 限制xargs每个进程使用一个输入行
  • -t- 在执行命令时打印它们

相关内容