[英]bash reverse order of comma separated values
I've got the following list of elements: 我有以下元素列表:
a, b, c, 1337, d, e
I wish I have: 我希望我有:
e, d, 1337, c, b, a
How can I achieve that in bash? 我怎样才能在bash中实现这一目标?
You can do this with awk
: 你可以用
awk
做到这一点:
#!/bin/bash
awk 'BEGIN{FS=",[ ]*"; OFS=", "}
{
for (i=NF; i>0; i--) {
printf "%s", $i;
if (i>1) {
printf "%s", OFS;
}
}
printf "\n"
}'
Explanation of the script: 脚本说明 :
FS=",[ ]*";
: The regex for Field Separator (delimiter for your input) matches a comma followed by zero or more spaces, so your input can be any of: a, b, c, 1337, d, e
a,b,c,1337,d,e
a, (many spaces) b, c,1337,d, e
OFS=", "
: The Output Field Separator (delimiter for your output) will be explicitly a comma followed by a space (so output looks consistent) OFS=", "
: 输出字段分隔符 ( 输出的分隔符)将显式为逗号,后跟空格(因此输出看起来一致) for (i=NF; i>0; i--) { ... }
: NF
means the Number of Fields in the current line. for (i=NF; i>0; i--) { ... }
: NF
表示当前行中的字段数 。 Here we iterate backwards, printing from the last field to the first field. if (i>1) { ... }
: Only print the OFS
if it's not the last field in the output if (i>1) { ... }
:如果OFS
不是输出中的最后一个字段,则仅打印OFS
printf "\\n"
: new line. printf "\\n"
:新行。 Sample usage : 样品用法 :
$ ./script_name < input_file > output_file
This solution is not very elegant, but should work with any number of fields: 这个解决方案不是很优雅,但应该适用于任意数量的字段:
sed 's/, /\n/g' | tac | sed ':a;$!{N;ba};s/\n/, /g'
Either pipe you data to it or give a file as second argument to first sed
(it will print the whole file as one comma-separated line, though). 要么将数据传输给它,要么将文件作为第一个
sed
第二个参数(它将整个文件打印为一个以逗号分隔的行)。
If your input is simple, and the number of columns is static, you could always go with a hardcoded awk
solution: 如果您的输入很简单,并且列数是静态的,您可以随时使用硬编码的
awk
解决方案:
awk -F, '{ print $6", "$5", "$4", "$3", "$2", "$1 }'
This assumes that you have 6 columns that are separated by a comma. 这假设您有6个用逗号分隔的列。 If you have a "comma + space" delimiter,
,
, you can use -F', '
instead of just -F,
. 如果你有一个“逗号+空格”分隔符
,
你可以使用-F', '
而不只是-F,
A straightforward example usage with output: 输出的简单示例用法:
$ echo "a, b, c, 1337, d, e" | awk -F', ' '{ print $6", "$5", "$4", "$3", "$2", "$1 }'
e, d, 1337, c, b, a
With a file as input: 使用文件作为输入:
awk -F', ' '{ print $6", "$5", "$4", "$3", "$2", "$1 }' your_file
You can then redirect the output from that to another file by appending > reversed_columns
; 然后,您可以通过附加
> reversed_columns
将输出重定向到另一个文件; "reversed_columns" being the name of the new file in this case. “reversed_columns”是这种情况下新文件的名称。
With the following script, it doesn't matter how many elements are in the list: 使用以下脚本,列表中有多少元素无关紧要:
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
Also, you can use the following perl one-liner (it will add a \\n
after the first element though) 此外,您可以使用以下perl one-liner(它会在第一个元素之后添加
\\n
)
echo "a, b, c, 1337, d, e" | perl -ne 'foreach(reverse(split(", ",$_))){print "$_, "}'
$ awk -F", " '{for (i=NF;i;i--) printf "%s ",$i; print ""}' < datafile
e d 1337 c b a
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
)
I use parentheses to create a subshell so I don't alter the IFS variable in the current shell. 我使用括号创建子shell,所以我不改变当前shell中的IFS变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.