我想在Linux上将所有文件作为单个parameter passing,但是我无法做到这一点。
这是工作
ls | sort -n | xargs -i pdftk {} cat output combinewd2.pdf
这每个命令传递一个参数,但是我希望所有命令都在一个命令中。
这是做到这一点的一种方法
pdftk $(ls | sort -n) cat output combinewd2.pdf
或者使用反引号
pdftk `ls | sort -n` cat output combinewd2.pdf
正如在注释中指出的那样,这将不适用于包含空格的文件名。 在这种情况下,你可以使用eval
eval pdftk $(while IFS= read -r file; do echo \"$file\" done < <(ls | sort -n)) cat output combinewd2.pdf
假设有两个名为“0 foo”和“1 bar”的文件,那么eval的结果就是所需的命令,文件名用双引号括起来:
pdftk " 0 foo " " 1 bar " cat output combinewd2.pdf
如果文件名可能包含换行符,则使用find
命令,请参阅@ andrewdotn答案的评论中的@joeytwiddle的讨论。 以下解决方案还使用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
这很丑,但是你可以运行sh -c
并访问xargs
传递的参数列表作为"${@}"
,如下所示:
ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}"
最后多余的"${0}"
在那里,因为正如sh
man页面所说的那样
-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
所有的参数都被正确引用。 请注意,如果任何文件名包含换行符,则这将失败,并且ls -v
基本上是ls | sort -n
ls | sort -n
使用-I
选项:
echo prefix | xargs -I % echo % post
输出:
prefix post
这应该适用于包含空格,换行符,撇号和引号(在UNIX文件系统上都可以)的文件名:
find . -maxdepth 1 -type f -print0 | sort -zn | xargs -0 sh -c 'pdftk "$@" cat output combinewd2.pdf' "$0"
如果您知道您正在使用简单的文件名,那么与接受的答案相比,这可能是矫枉过正的。
但是如果你正在编写一个将来会再次使用的脚本,那么当它遇到异常(但是有效)的输入时,它是不会有一天爆发的。
这基本上是一个适应了andrewdotn的答案,它终止零字节的输入文件,而不是一个换行符,因此保留包含一个或多个换行符的文件名。
相应的选项-print0
, -z
和-0
告诉每个程序输入/输出应该由零字节分隔。 三个不同的方案,三个不同的论点!
这里的问题是,虽然xargs可以用-i
和{}
在命令的中间放置单独的参数,但它拒绝为多个参数执行此操作。 这似乎是一个疏忽,最终导致我们很多麻烦!
除了上面的解决方案之外,另一种方法是将文件后面的参数简单地添加到文件列表的末尾。
( ls | sort -n echo cat echo output echo combinewd2.pdf ) | xargs -d'\n' pdftk
这种方法不适用于包含换行符的文件名 。 对于这种罕见的情况,您应该将以零字节结尾的行传递给xargs,如我的其他答案中所提供的。