xargs 的 -i 和 -I 之间的区别

xargs 的 -i 和 -I 之间的区别

我理解,-i但我不知道它与手册有何不同-I以及为什么手册说它-i已被弃用。例如,使用下面两行有什么区别:

ls -t | tail -n 4 | xargs -I{} mv {} test2/

ls -t | tail -n 4 | xargs -i mv {} test2/

对于第一行,任何内容都可以被替换到第一行{}的前面-I,还是这只是语法?

谢谢

答案1

它被弃用的原因是维护者决定xargs它应该被弃用。没有太多可说的了1。这些是man xargs我的 Arch 系统的相关部分:

       -I replace-str
              Replace occurrences of  replace-str  in  the  initial-arguments
              with  names read from standard input.  Also, unquoted blanks do
              not terminate input items; instead the separator is the newline
              character.  Implies -x and -L 1.

       -i[replace-str], --replace[=replace-str]
              This  option  is  a synonym for -Ireplace-str if replace-str is
              specified.  If the replace-str argument is missing, the  effect
              is  the  same  as  -I{}.  This option is deprecated; use -I in‐
              stead.

-i因此,和之间的唯一区别-I是,-i不带参数的情况下会被视为-I{}。字符串{}经常用于这种事情并且已经成为一种约定。例如,在其动作中也以类似的方式find使用:{}-exec

      -exec command {} +
              This variant of the -exec action runs the specified command  on
              the  selected files, but the command line is built by appending
              each selected file name at the end; the total number of invoca‐
              tions  of  the  command  will  be  much less than the number of
              matched files.  The command line is built in much the same  way
              that xargs builds its command lines.  Only one instance of `{}'
              is allowed within the command, and it must appear at  the  end,
              immediately before the `+'; it needs to be escaped (with a `\')
              or quoted to protect it from interpretation by the shell.   The
              command  is executed in the starting directory.  If any invoca‐
              tion with the `+' form returns a non-zero value as exit status,
              then  find  returns a non-zero exit status.  If find encounters
              an error, this can sometimes cause an immediate exit,  so  some
              pending  commands  may  not  be  run  at  all.  For this reason
              -exec my-command ... {} + -quit may not  result  in  my-command
              actually being run.  This variant of -exec always returns true.

但是,这只是一个约定,因此xargs并不强迫您使用它。您可以使用任何东西来代替{}xargs' -I。例如:

$ seq 5 | xargs -I'&' echo "I read &"
I read 1
I read 2
I read 3
I read 4
I read 5

甚至:

$ seq 5 | xargs -I'a' echo "I read a"
I re1d 1
I re2d 2
I re3d 3
I re4d 4
I re5d 5

因此,当给定一个字符串时,该-i选项要么 100% 等效于-I,要么是 特定情况的简写-I{},这意味着它告诉xargs使用{}就像您已明确指定它一样:

$ seq 5 | xargs -i'a' echo "I read a"  ## as above
I re1d 1
I re2d 2
I re3d 3
I re4d 4
I re5d 5

$ seq 5 | xargs -i echo "I read {}"  ## implies -I{}
I read 1
I read 2
I read 3
I read 4
I read 5

$ seq 5 | xargs -I echo "I read {}"  ## breaks because -I requires a string
xargs: I read {}: No such file or directory

显然,维护者认为xargs这不再是一个好主意,因此该选项现已弃用,并且可能会从未来版本中删除。


1看来还有更多话要说。约尔格·W·米塔格在评论(现已删除)中指出了以下内容:

请注意,不仅仅是 xargs 的维护者做出了这样的决定。 -i 也因“过时”而从 SUSv6 (2004) 中删除。即使 -I 不是 SUS 核心的一部分,它也只是定义为(可选)XSI 扩展的一部分。因此,即使是保守的标准作者也认为它太古老了,几乎已经是二十年前的事了。

相关内容