执行 “| xargs” 时没有提供任何参数是否有任何好处?

huangapple go评论134阅读模式
英文:

Is there any benefit of executing "| xargs" without any arguments?

问题

我发现有些脚本中执行了 | xargs,但没有提供任何参数。我开始删除这些情况,因为脚本似乎可以正常运行,但我想确认我是否漏掉了什么。也许 xargs 默认会对某些字符进行清理等操作。

以下是您提到的代码部分:

... | cut -d: -f2- | xargs

请问上面的 | xargs 是否有必要?提前感谢您的回答。

英文:

I came across scripts where | xargs is executed without any arguments. I started removing such occurrences because scripts just work without them but wanted to verify that I'm not missing something. Perhaps xargs defaults to sanitising some characters, etc.

... | cut -d: -f2- | xargs

Is there any point of having the | xargs above? Thanks in advance.

答案1

得分: 5

没有任何参数时,xargs 将会合并输出中的所有行成一行,并移除额外的空格:

$ echo $'a   b\nb'
a   b
b

$ echo $'a   b\nb' | xargs
a b b

请注意,这只适用于 xargs 的输入小于命令缓冲区的最大大小。请参见下面的示例:

$ seq 100 | xargs | wc -l
1
$ seq 1000000 | xargs | wc -l
53
英文:

Without any arguments xargs will combine all lines in the output into a single line, and will remove extra spaces:

$ echo $'a   b\nb'
a   b
b

$ echo $'a   b\nb' | xargs
a b b

Note that this will only work if the input of xargs is smaller than the maximum size of the command buffer. See example below:

$ seq 100 | xargs | wc -l
1
$ seq 1000000 | xargs | wc -l
53

答案2

得分: 1

根据 @user000001 的回答,从标准输入(stdin)中清除空白字符(包括换行符),使其成为漂亮的一行单空格分隔的值。

当您需要在 shell 命令行界面中“连接”这些值时(通过“连接”,我指的是在所有值之间添加分隔符),一个有趣的用例出现了,例如,您想要计算当前目录中所有文件的大小之和(类似于某种程度上的 du):

$ stat *|sed -n 's/^size//p'|xargs
5589886 11669381 4096 1743 2467 4096 22447289 1784723 27472 203 4096 525 4096 4096 4511158 268533 131068 150307 75658 12288 4096 4096 102762 4096 4096 4096 7296 5782043 4096 4096 779 14855386 895468 4096 4096 227

# 通过将 `xargs` 中的每个单个空格替换为 `+`,并将其传递给 `bc`
# 以获得所有数字的总和
$ stat *|sed -n 's/^size//p'|xargs|sed 's/ /+/g'|bc -l
68374006

请注意:上述代码块中的注释和代码示例未被翻译。

英文:

As per @user000001's answer, it's useful to "cleanup" whitespaces (including newlines) from stdin, into nicely one-line single-space separated values.

An interesting use-case arises when you need to "join" these values in a shell CLI (by join I mean adding a separator between all values), for example, you want to sum the size of all files in your current directory (similar to du somehow):

$ stat *|sed -n 's/^size//p'|xargs
5589886 11669381 4096 1743 2467 4096 22447289 1784723 27472 203 4096 525 4096 4096 4511158 268533 131068 150307 75658 12288 4096 4096 102762 4096 4096 4096 7296 5782043 4096 4096 779 14855386 895468 4096 4096 227

# replace each single whitespace from `xargs` by `+` and pipe it to `bc`
# to get the sum of all numbers
$ stat *|sed -n 's/^size//p'|xargs|sed 's/ /+/g'|bc -l
68374006

答案3

得分: 1

以下是您要翻译的内容:

This construct might seem useful to flatten the input with echo (which is called by xargs by default) but it has a few border cases depending on the content of stdin AND the implementation of echo:

  1. it might trim leading/trailing/duplicate white spaces:

    printf '%s\n' '  a' 'b  b' 'c  ' | xargs
    
    a b b c
    
  2. as @user000001 explained, when the input is too long, echo will be called multiple times, giving you multiple lines of output

  3. xargs has its own escaping rules; for example the presence of single/double quotes in the input might break the command:

    printf '%s\n' "I'll be there" | xargs
    
    xargs: unmatched single quote
    
  4. echo has undefined behaviors; the output of

    printf '%s\n' 'a\\nb' | xargs    # \\ means \ for xargs
    

    could be

    a\nb
    

    as well as

    a
    b
    

ASIDE

For a sure-fire method of flattening the input, I would replace:

... | cut -d: -f2- | xargs

with:

... | cut -d: -f2- | paste -sd ' ' | sed 's/ \+/ /g; s/^ //; s/ $//'

note: the sed is for trimming leading/trailing/duplicate white spaces

英文:

This construct might seem useful to flatten the input with echo (which is called by xargs by default) but it has a few border cases depending on the content of stdin AND the implementation of echo:

  1. it might trim leading/trailing/duplicate white spaces:

    printf '%s\n' '  a' 'b  b' 'c  ' | xargs
    
    a b b c
    
  2. as @user000001 explained, when the input is too long, echo will be called multiple times, giving you multiple lines of output

  3. xargs has it's own escaping rules; for example the presence of single/double quotes in the input might break the command:

    printf '%s\n' "I'll be there" | xargs
    
    xargs: unmatched single quote
    
  4. echo has undefined behaviors; the output of

    printf '%s\n' 'a\\nb' | xargs    # \\ means \ for xargs
    

    could be

    a\nb
    

    as well as

    a
    b
    

ASIDE

For a sure-fire method of flattening the input, I would replace:

... | cut -d: -f2- | xargs

with:

... | cut -d: -f2- | paste -sd ' ' | sed 's/ \+/ /g; s/^ //; s/ $//'

<sup>note: the sed is for trimming leading/trailing/duplicate white spaces</sup>

huangapple
  • 本文由 发表于 2023年3月9日 20:42:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75684777.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定