如何执行`xargs`的相反操作?

21

我有一个数字列表需要反转。

它们已经排序好了。

35 53 102 342

我想要这个:

342 102 53 35

所以我考虑了这个:

echo $NUMBERS | ??? | tac | xargs

???是什么?

它应该将以空格分隔的列表转换为以行分隔的列表。

我希望避免设置IFS

也许我可以使用bash数组,但我希望有一种命令的目的是做xargs的相反操作(也许xargs不止于此!)

8个回答

24

你可以使用 printf 来实现这个功能。例如:

$ printf "%s\n" 35 53 102 342
35
53
102
342
$ printf "%s\n" 35 53 102 342|tac
342
102
53
35

2
哇,这就是我所说的惊喜。 - Steven Lu
3
最好使用 %s,这样如果数字包含小数点或太大而不会��错。 - mark4o
@mark4o:我完全没有考虑过那个问题,谢谢你的提示。 - Mat
...或者具有前导0和无效的八进制数字。举个完全随意的例子,我从未遇到过。 - Mark Reed

13

另一个回答(容易记住但不如printf方法快):

$ xargs -n 1 echo
例如。
$ NUMBERS="35 53 102 342"
$ echo $NUMBERS | xargs -n 1 echo | tac | xargs
342 102 53 35

这里是xargs-n选项手册:

-n number
         Set the maximum number of arguments taken from standard input for 
         each invocation of utility.  An invocation of utility will use less 
         than number standard input arguments if the number of bytes accumu-
         lated (see the -s option) exceeds the specified size or there are 
         fewer than number arguments remaining for the last invocation of 
         utility.  The current default value for number is 5000.

当我寻找xargs的反向操作时,这正是我所需要的,谢谢。由于echo是xargs使用的标准命令,因此您甚至可以像echo $NUMBERS | xargs -n1 | tac | xargs一样省略它。 - Mitja

8

不使用tac的awk单行代码:

awk '{NF++;while(NF-->1)print $NF}'

例如:
kent$  echo "35 53 102 342"|awk '{NF++;while(NF-->1)print $NF}'
342
102
53
35

5

另一种方法是使用Bash字符串操作

,这可以与IT技术有关。

$ numbers="35 53 102 342"
$ echo "${numbers// /$'\n'}"
35
53
102
342
$ echo "${numbers// /$'\n'}" | tac
342
102
53
35

3

好的,您可以这样写:

echo $(printf '%s\n' $NUMBERS | tac)

其中,printf '%s\n' ... 会打印出每一个 ...,并在每个之后换行。而 $( ... ) 是一个内置的功能,使得 xargs 几乎变得不必要。

然而,我认为你不应该避免使用数组、IFS 等等;它们可以让脚本更加鲁棒,面对错误和/或意外输入时更加健壮。


3

很多回答都使用了tac,但如果你想使用sort,那么几乎是一样的:

printf "%s\n" 1 2 3 4 5 10 12 | sort -rn

n是非常重要的,因为它可以使数字排序。 r表示反向排序。


2
如果您使用sort对列表进行了排序,您可能会考虑使用-r反转选项。

1

使用tr也可以将空格转换为换行符,反之亦然:

echo 35 53 102 342|tr ' ' '\n'|tac|tr '\n' ' '

如果数据未排序,请将 tac 替换为 sort -rn。保留html。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接