7

我有以下元素列表:

a, b, c, 1337, d, e

我希望我有:

e, d, 1337, c, b, a

我怎样才能在 bash 中实现这一点?

4

6 回答 6

5

你可以这样做awk

#!/bin/bash

awk 'BEGIN{FS=",[ ]*"; OFS=", "}
    {
        for (i=NF; i>0; i--) {
            printf "%s", $i;
            if (i>1) {
                printf "%s", OFS;
            }
        }
        printf "\n"
    }'

脚本解释

  • FS=",[ ]*";字段分隔符(输入的分隔符)的正则表达式匹配逗号,后跟零个或多个空格,因此您的输入可以是以下任何一种:
    • a, b, c, 1337, d, e
    • a,b,c,1337,d,e
    • a, (many spaces) b, c,1337,d, e
  • OFS=", "输出字段分隔符(输出的分隔符​​)将明确地是一个逗号后跟一个空格(因此输出看起来一致)
  • for (i=NF; i>0; i--) { ... }:NF表示当前行的字段数。这里我们向后迭代,从最后一个字段打印到第一个字段。
  • if (i>1) { ... }:仅打印OFS如果它不是输出中的最后一个字段
  • printf "\n": 新队。

示例用法

$ ./script_name < input_file > output_file
于 2012-11-13T19:13:40.570 回答
2

如果您的输入很简单,并且列数是静态的,那么您总是可以使用硬编码的awk解决方案:

awk -F, '{ print $6", "$5", "$4", "$3", "$2", "$1 }'

这假设您有 6 列用逗号分隔。如果您有“逗号 + 空格”分隔符,,则可以使用.-F', '而不是-F,.

带有输出的简单示例用法:

$ echo "a, b, c, 1337, d, e" | awk -F', ' '{ print $6", "$5", "$4", "$3", "$2", "$1 }'
e, d, 1337, c, b, a

使用文件作为输入:

awk -F', ' '{ print $6", "$5", "$4", "$3", "$2", "$1 }' your_file

然后,您可以通过附加将输出从该文件重定向到另一个文件> reversed_columns;在这种情况下,“reversed_columns”是新文件的名称。

于 2012-11-13T19:12:22.417 回答
2

这个解决方案不是很优雅,但应该适用于任意数量的字段:

sed 's/, /\n/g' | tac | sed ':a;$!{N;ba};s/\n/, /g'

要么通过管道将数据传递给它,要么将文件作为第二个参数提供给 first sed(不过,它会将整个文件打印为一个逗号分隔的行)。

于 2012-11-13T19:14:42.983 回答
2
$ awk -F", " '{for (i=NF;i;i--) printf "%s ",$i; print ""}' < datafile
e d 1337 c b a 
于 2012-11-13T19:22:35.630 回答
1

使用以下脚本,列表中有多少元素并不重要:

IFS=', '; read -a array <<< "a, b, c, 1337, d, e"
let i=${#array[@]}-1; 
while [ $i -ge 0 ]; do 
    echo -n "${array[$i]}, "; 
    let i--; 
done

此外,您可以使用以下 perl one-liner(它会\n在第一个元素之后添加一个)

echo "a, b, c, 1337, d, e" | perl -ne 'foreach(reverse(split(", ",$_))){print "$_, "}'
于 2012-11-13T19:21:42.177 回答
1

重击:

echo "a, b, c, 1337, d, e" | (
  IFS=", "
  while read line; do
    set -- $line
    for (( i=$#; i > 1; i-- )); do
      printf "%s, " "${!i}"
    done
    echo "$1"
  done
)

我使用括号来创建一个子shell,因此我不会更改当前shell 中的IFS 变量。

于 2012-11-13T19:48:56.087 回答