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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14639206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:53:26  来源:igfitidea点击:

How can I pass all arguments with xargs in middle of command in linux

linuxxargs

提问by user2027303

I want to pass all the files as a single argument on Linux but I am not able to do that.

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

This is working

这是工作

ls | sort -n | xargs  -i pdftk  {} cat output combinewd2.pdf

This passes a single argument per command, but I want all in one command.

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

采纳答案by amdn

This is one way to do it

这是一种方法

pdftk $(ls | sort -n) cat output combinewd2.pdf

or using backtick

或使用反引号

pdftk `ls | sort -n` cat output combinewd2.pdf

As pointed out in the comments this will not work on filenames containing spaces. In that case you could use eval

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

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

Suppose there are two files named " 0 foo " and " 1 bar " then the result of eval would be the desired command, with the file names in double quotes:

假设有两个名为“ 0 foo ”和“ 1 bar ”的文件,那么 eval 的结果将是所需的命令,文件名用双引号括起来:

pdftk " 0 foo " " 1 bar " cat output combinewd2.pdf

If the filenames might contain newlines, then use findcommand, see discussion by @joeytwiddle in the comments of @andrewdotn's answer. The following solution also handles file names with double quotes using the sedcommand to escape double quotes:

如果文件名可能包含换行符,则使用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

回答by andrewdotn

It's ugly, but you can run sh -cand access the list of arguments passed by xargsas "${@}", like so:

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

ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "
$ 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' "
find . -maxdepth 1 -type f -print0 |
  sort -zn |
  xargs -0 sh -c 'pdftk "$@" cat output combinewd2.pdf' "
echo prefix | xargs -I % echo % post
"
" + 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
"

The extra "${0}"at the end is there because, as the shman page says

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

-cstring

If the -coption is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.

-c字符串

如果存在-c选项,则从string读取命令。如果string之后有参数,则将它们分配给位置参数,从$0开始。

To test this, let's first create some files with complicated names that will mess up most other solutions:

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

prefix post

All the arguments are quoted correctly. Note that this will fail if any filenames contain newlines, and that ls -vis basically ls | sort -n.

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

回答by joeytwiddle

This should work on filenames containing spaces, newlines, apostrophes and quotation marks (all of which are possible on UNIX filesystems):

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

ls | sort -n | xargs echo | xargs -I {} pdftk {} cat output combinewd2.pdf

That might be overkill compared to the accepted answer, if you know you are working with simple filenames.

如果您知道自己使用的是简单的文件名,那么与接受的答案相比,这可能有点矫枉过正。

But if you are writing a script that will be used again in future, it is desirable that it won't explode one day when it meets unusual (but valid) inputs.

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

This is basically an adaptation of andrewdotn's answer which terminates input files with a zero-byte, instead of with a newline, hence preserving filenames which contain one or more newline characters.

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

The respective options -print0, -zand -0tell each of the programs that input/output should be delimited by the zero-byte. Three different programs, three different arguments!

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

回答by Hongbo Liu

Use -Ioption:

使用-I选项:

find .|grep txt$|xargs -I{} echo "mv {} {}.json"|bash

Output:

输出:

find $PWD|grep txt$|cut -d"." -f1|xargs -I{} echo "mv {}.txt {}.json"|bash

回答by JakeRobb

You can do this by chaining two calls to xargs. Use the first to chain all of the args together into one string and pass that as a param to echo, and the second using -Ito place that chain of args into the place where you want it, as follows:

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

find .|grep txt|xargs -I{} echo "echo End of File >> {}"|bash

回答by Thyag

The most intuitive way I found was to:

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

  • first construct the commands with -I{} and "echo",
  • then execute the commands with "bash" (as if you are executing a shell script)
  • 首先用 -I{} 和“echo”构造命令,
  • 然后用“bash”执行命令(就像你在执行一个shell脚本一样)

Here is an example to rename extensions from ".txt" to ".txt.json":

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

cat chapter_order-pdf-sample.txt | xargs -J % pdftk % cat output sample.pdf

Slightly advanced example to rename .txt to .json (removing .txt extension)

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

##代码##

I once had a requirement to append the string "End of File" to all files.

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

##代码##

If you do it right, xargs is the king of all commands!

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

回答by brian d foy

Here's what I did for the same problem, and am actually using in production:

这是我为同样的问题所做的,实际上是在生产中使用的:

##代码##