我有以下元素列表:
a, b, c, 1337, d, e
我希望我有:
e, d, 1337, c, b, a
我怎样才能在bash中实现这一目标?
答案 0 :(得分:4)
您可以使用 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
:新行。示例用法:
{{1}}
答案 1 :(得分:2)
此解决方案不是很优雅,但应该适用于任意数量的字段:
sed 's/, /\n/g' | tac | sed ':a;$!{N;ba};s/\n/, /g'
将数据传输给它或将文件作为第二个参数提供给第一个sed
(它会将整个文件打印为一个以逗号分隔的行)。
答案 2 :(得分:1)
如果您的输入很简单,且列数是静态的,您可以随时使用硬编码的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”是这种情况下新文件的名称。
答案 3 :(得分: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 "$_, "}'
答案 4 :(得分:1)
$ awk -F", " '{for (i=NF;i;i--) printf "%s ",$i; print ""}' < datafile
e d 1337 c b a
答案 5 :(得分:1)
bash:
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变量。