如何在linux中的命令中间使用xargs传递所有参数

use*_*303 16 linux xargs

我想在Linux上将所有文件作为单个参数传递,但我无法做到这一点.

这很有效

ls | sort -n | xargs  -i pdftk  {} cat output combinewd2.pdf
Run Code Online (Sandbox Code Playgroud)

这会为每个命令传递一个参数,但我希望所有命令都在一个命令中.

Hon*_*Liu 21

使用-I选项:

echo prefix | xargs -I % echo % post
Run Code Online (Sandbox Code Playgroud)

输出:

prefix post
Run Code Online (Sandbox Code Playgroud)

  • 但是,如果您使用`ls`而不是`echo'作为输入,这将无法按需工作(它调用命令三次,而不是使用三个参数一次),而这正是OP试图做到的。 。 (5认同)
  • 不知道为什么它被评为最高票数。作者问的是“传递所有论点”,而这个并没有回答这个问题。 (3认同)

amd*_*mdn 16

这是一种方法

pdftk $(ls | sort -n) cat output combinewd2.pdf
Run Code Online (Sandbox Code Playgroud)

或使用反引号

pdftk `ls | sort -n` cat output combinewd2.pdf
Run Code Online (Sandbox Code Playgroud)

正如评论中所指出的,这不适用于包含空格的文件名.在那种情况下你可以使用eval

eval pdftk $(while IFS= read -r file; do
    echo \"$file\"
done < <(ls | sort -n)) cat output combinewd2.pdf
Run Code Online (Sandbox Code Playgroud)

假设有两个名为"0 foo"和"1 bar"的文件,则eval的结果将是所需的命令,文件名称为双引号:

pdftk " 0 foo " " 1 bar " cat output combinewd2.pdf
Run Code Online (Sandbox Code Playgroud)

如果文件名可能包含换行符,则使用find命令,参见@joeytwiddle在@andrewdotn的回答评论中的讨论.以下解决方案还使用双引号来处理带双引号的文件名sed:

eval pdftk $(while IFS= read -r -d '' file; do
    echo \"$file\"
done < <(find . -maxdepth 1 -type f -print0 | \
    sed 's/"/\\"/g'| sort -zn)) cat output combinewd2.pdf
Run Code Online (Sandbox Code Playgroud)

  • 一个非常"以bash为中心"的答案,但很酷.但是,这在`csh/tcsh`中不起作用.(关于shell选择的所有评论>`/ dev/null`) (2认同)
  • 我担心您的 eval 解决方案不适用于包含 `"` 引号 `"` 的文件名。当我们知道文件名没有空格时,我确实喜欢你的 `$(...)` 方法的简单性。我已将我的解决方案作为单独的答案发布。 (2认同)

and*_*otn 10

这很难看,但你可以运行sh -c并访问xargsas 传递的参数列表"${@}",如下所示:

ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}"
Run Code Online (Sandbox Code Playgroud)

最后的额外"${0}"是因为,正如sh手册页所说

-c 字符串

如果存在-c选项,则从字符串中读取命令.如果字符串后面有参数,则将它们分配给位置参数,从$ 0开始.

为了测试这一点,让我们首先创建一些具有复杂名称的文件,这些文件会破坏大多数其他解决方案:

$ seq 1 100 | xargs -I{} touch '{} with "spaces"'
$ ls
1 with "spaces"    31 with "spaces"  54 with "spaces"  77 with "spaces"
10 with "spaces"   32 with "spaces"  55 with "spaces"  78 with "spaces"
100 with "spaces"  33 with "spaces"  56 with "spaces"  79 with "spaces"
11 with "spaces"   34 with "spaces"  57 with "spaces"  8 with "spaces"
12 with "spaces"   35 with "spaces"  58 with "spaces"  80 with "spaces"
13 with "spaces"   36 with "spaces"  59 with "spaces"  81 with "spaces"
14 with "spaces"   37 with "spaces"  6 with "spaces"   82 with "spaces"
15 with "spaces"   38 with "spaces"  60 with "spaces"  83 with "spaces"
16 with "spaces"   39 with "spaces"  61 with "spaces"  84 with "spaces"
17 with "spaces"   4 with "spaces"   62 with "spaces"  85 with "spaces"
18 with "spaces"   40 with "spaces"  63 with "spaces"  86 with "spaces"
19 with "spaces"   41 with "spaces"  64 with "spaces"  87 with "spaces"
2 with "spaces"    42 with "spaces"  65 with "spaces"  88 with "spaces"
20 with "spaces"   43 with "spaces"  66 with "spaces"  89 with "spaces"
21 with "spaces"   44 with "spaces"  67 with "spaces"  9 with "spaces"
22 with "spaces"   45 with "spaces"  68 with "spaces"  90 with "spaces"
23 with "spaces"   46 with "spaces"  69 with "spaces"  91 with "spaces"
24 with "spaces"   47 with "spaces"  7 with "spaces"   92 with "spaces"
25 with "spaces"   48 with "spaces"  70 with "spaces"  93 with "spaces"
26 with "spaces"   49 with "spaces"  71 with "spaces"  94 with "spaces"
27 with "spaces"   5 with "spaces"   72 with "spaces"  95 with "spaces"
28 with "spaces"   50 with "spaces"  73 with "spaces"  96 with "spaces"
29 with "spaces"   51 with "spaces"  74 with "spaces"  97 with "spaces"
3 with "spaces"    52 with "spaces"  75 with "spaces"  98 with "spaces"
30 with "spaces"   53 with "spaces"  76 with "spaces"  99 with "spaces"
$  ls | sort -n | xargs -d'\n' sh -c 'set -x; pdftk "${@}" cat output combinewd2.pdf' "${0}"
+ pdftk '1 with "spaces"' '2 with "spaces"' '3 with "spaces"' '4 with "spaces"' '5 with "spaces"' '6 with "spaces"' '7 with "spaces"' '8 with "spaces"' '9 with "spaces"' '10 with "spaces"' '11 with "spaces"' '12 with "spaces"' '13 with "spaces"' '14 with "spaces"' '15 with "spaces"' '16 with "spaces"' '17 with "spaces"' '18 with "spaces"' '19 with "spaces"' '20 with "spaces"' '21 with "spaces"' '22 with "spaces"' '23 with "spaces"' '24 with "spaces"' '25 with "spaces"' '26 with "spaces"' '27 with "spaces"' '28 with "spaces"' '29 with "spaces"' '30 with "spaces"' '31 with "spaces"' '32 with "spaces"' '33 with "spaces"' '34 with "spaces"' '35 with "spaces"' '36 with "spaces"' '37 with "spaces"' '38 with "spaces"' '39 with "spaces"' '40 with "spaces"' '41 with "spaces"' '42 with "spaces"' '43 with "spaces"' '44 with "spaces"' '45 with "spaces"' '46 with "spaces"' '47 with "spaces"' '48 with "spaces"' '49 with "spaces"' '50 with "spaces"' '51 with "spaces"' '52 with "spaces"' '53 with "spaces"' '54 with "spaces"' '55 with "spaces"' '56 with "spaces"' '57 with "spaces"' '58 with "spaces"' '59 with "spaces"' '60 with "spaces"' '61 with "spaces"' '62 with "spaces"' '63 with "spaces"' '64 with "spaces"' '65 with "spaces"' '66 with "spaces"' '67 with "spaces"' '68 with "spaces"' '69 with "spaces"' '70 with "spaces"' '71 with "spaces"' '72 with "spaces"' '73 with "spaces"' '74 with "spaces"' '75 with "spaces"' '76 with "spaces"' '77 with "spaces"' '78 with "spaces"' '79 with "spaces"' '80 with "spaces"' '81 with "spaces"' '82 with "spaces"' '83 with "spaces"' '84 with "spaces"' '85 with "spaces"' '86 with "spaces"' '87 with "spaces"' '88 with "spaces"' '89 with "spaces"' '90 with "spaces"' '91 with "spaces"' '92 with "spaces"' '93 with "spaces"' '94 with "spaces"' '95 with "spaces"' '96 with "spaces"' '97 with "spaces"' '98 with "spaces"' '99 with "spaces"' '100 with "spaces"' cat output combinewd2.pdf
Run Code Online (Sandbox Code Playgroud)

所有参数都被正确引用.请注意,如果任何文件名包含换行符,这将失败,ls -v基本上就是这样ls | sort -n.


joe*_*dle 7

这应该适用于包含空格,换行符,撇号和引号的文件名(在UNIX文件系统上所有这些都是可能的):

find . -maxdepth 1 -type f -print0 |
  sort -zn |
  xargs -0 sh -c 'pdftk "$@" cat output combinewd2.pdf' "$0"
Run Code Online (Sandbox Code Playgroud)

如果您知道您使用的是简单的文件名,那么与接受的答案相比,这可能是过高的选择。

但是,如果您编写的脚本将来会再次使用,则希望脚本在遇到异常(但有效)输入时不会在一天之内爆炸。

这基本上是对安德鲁多顿答案的改编,它以零字节而不是换行符终止输入文件,因此保留了包含一个或多个换行符的文件名。

各个选项-print0-z-0告诉每个程序输入/输出应以零字节分隔。三种不同的程序,三种不同的论点!


Thy*_*yag 7

我发现的最直观的方法是:

  • 首先用 -I{} 和“echo”构造命令,
  • 然后用“bash”执行命令(就像你在执行一个shell脚本一样)

以下是将扩展名从“.txt”重命名为“.txt.json”的示例:

find .|grep txt$|xargs -I{} echo "mv {} {}.json"|bash
Run Code Online (Sandbox Code Playgroud)

将 .txt 重命名为 .json 的稍微高级的示例(删除 .txt 扩展名)

find $PWD|grep txt$|cut -d"." -f1|xargs -I{} echo "mv {}.txt {}.json"|bash
Run Code Online (Sandbox Code Playgroud)

我曾经要求将字符串“文件结尾”附加到所有文件。

find .|grep txt|xargs -I{} echo "echo End of File >> {}"|bash
Run Code Online (Sandbox Code Playgroud)

如果你做对了,xargs 就是所有命令之王!


Jak*_*obb 5

您可以通过将两个调用链接到 xargs 来做到这一点。使用第一个将所有 args 链接到一个字符串中并将其作为参数传递给echo,第二个-I用于将该 args 链放置到您想要的位置,如下所示:

ls | sort -n | xargs echo | xargs -I {} pdftk {} cat output combinewd2.pdf
Run Code Online (Sandbox Code Playgroud)


bri*_*foy 5

这是我针对同一问题所做的操作,并且实际上在生产中使用:

cat chapter_order-pdf-sample.txt | xargs -J % pdftk % cat output sample.pdf
Run Code Online (Sandbox Code Playgroud)