Losing formatting using “echo -e” in bash

2019-08-01 03:22发布

I'm having a problem with the following snippet:

while read line
do
     team1=`echo "${line% *}"`
     team2=`echo "${line#* }"`
     newline=`printf "%-8.2f\t%-8.2f\n" "$team1" "$team2"`
     #this line give perfect output
     # echo "$newline" 
     ##################problem is here########################
     final_list=("${final_list[@]}" "$newline")
     #########################################################
done <input.txt

#this line is losing all the formatting I gave
echo -e ${final_list[@]} | sort -t$'\t' -k1 -nr

This is my input file

3.01 16.12
1.12 13.22
3.01 14.12 

My expected output is

1.12            13.22   
3.01            14.12   
3.01            16.12 

标签: bash shell
2条回答
Bombasti
2楼-- · 2019-08-01 04:07

Use sort -n to sort the file (if needed redirect it to new file like > newfile.txt and use it)?

sort -n input.txt
查看更多
你好瞎i
3楼-- · 2019-08-01 04:08

Replace:

echo -e ${final_list[@]} | sort -t$'\t' -k1 -nr

with:

printf "%s\n" "${final_list[@]}" | sort -t$'\t' -k1 -n

This achieves your expected output:

$ printf "%s\n" "${final_list[@]}" | sort -t$'\t' -k1 -n
1.12            13.22   
3.01            14.12   
3.01            16.12   

There were two required changes. First, sort works line-by-line and the echo output produces a single line. Second, because your desired output was numerically sorted in ascending order, the -r flag needed to be removed from sort.

What went wrong

This line does not do what one would think:

 newline=`printf "%-8.2f\t%-8.2f\n" "$team1" "$team2"`

The problem is that, when the shell does command substitution, any trailing newline characters are deleted. So, the \n in the printf format is removed before the output is assigned to newline.

That means that when you get to here:

echo -e ${final_list[@]} 

There are no newlines. The echo output all appears on one line.

Now, consider:

 #this line give perfect output
 # echo "$newline" 

That works because echo adds its own newline to the output.

A simpler script

I don't know the structure of your big project, but, as a possible alternative to the code presented, consider:

while read team1 team2
do
     newline=$(printf "%-8.2f\t%-8.2f" "$team1" "$team2")
     final_list=("${final_list[@]}" "$newline")
done <input.txt
printf "%s\n" "${final_list[@]}" | sort -t$'\t' -k1 -n

Still simpler, but possibly not helpful in the big project, would be this code which reformats and sorts input.txt:

$ awk '{printf "%-8.2f\t%-8.2f\n",$1,$2}' input.txt |sort -n
1.12            13.22   
3.01            14.12   
3.01            16.12   
查看更多
登录 后发表回答