我在单个列中有正浮点值或负浮点值的数据,由两个空行分隔。
1.0
-2.0
3.0
4.0
-5.0
6.0
-7.0
8.0
在bash中,将这些数据放入多个列的最佳方法是什么,以便最终结果如下所示:
1.0 3.0 -5.0 -7.0
-2.0 4.0 6.0 8.0
在理想情况下,解决方案不仅适用于数字,还适用于以类似方式分隔的文本。
答案 0 :(得分:11)
怎么样:
$ grep -v '^\s*$' file | pr -ts" " --columns 4
1.0 3.0 -5.0 -7.0
-2.0 4.0 6.0 8.0
grep
用于删除空行,pr
用于格式化输出。
答案 1 :(得分:2)
这可能适合你(GNU sed):
sed -r '/./!d;$!N;2{h;d};G;s/^(.*)\n(.*)\n(.*)\n(.*)$/\3 \1\n\4 \2/;$!{h;d}' file
/./!d
如果该行不包含字符,则将其删除。$!N
如果该行不是最后一行,则添加换行符,并将以下行附加到模式空间(PS)。2{h;d}
,将PS复制到保留空间(HS),然后将其删除。G
将HS附加到PS。s/^(.*)\n(.*)\n(.*)\n(.*)$/\3 \1\n\4 \2/
将PS重新排列为所需的顺序。$!{h;d}
除了最后将PS复制到HS之外的所有行,然后删除PS。
这意味着在遇到最后一行时,PS的内容将被打印出来。答案 2 :(得分:1)
这是一个更长但更易读的解决方案:
a=() b=() i=0
while read line ; do
case $i in
0) a+=($line) ;;
1) b+=($line) ;;
esac
((i++))
if ((i == 4)); then i=0; fi
done < data.txt
echo ${a[*]}
echo ${b[*]}
答案 3 :(得分:0)
假设您的数据位于文件data.txt中;你可以试试这个:
a=($(< data.txt))
b(){ for((i=$1; i<${#a[*]}; i+=2)); do echo -n "${a[$i]} "; done; echo ;}
b 0
b 1
这肯定不是最好的方法,但它有效!
答案 4 :(得分:0)
您也可以尝试使用xargs first
while read a b
do
A+=($a) B+=($b)
done < <( xargs -n2 < file )
printf "%s\n" "${A[*]}" "${B[*]}"
-
或
while read a; read b; do
read; read;
A+=($a) B+=($b)
done < file
printf "%s\n" "${A[*]}" "${B[*]}"
答案 5 :(得分:0)
使用一次调用awk:
awk 'BEGIN{RS="\n\n\n"}{A=A " " $1;B=B " " $2}END{printf A "\n" B "\n"}' NewFile
仅使用posix shell(带内置)
#!/bin/sh
L=""
R=""
while read A && read B && read dummy && read dumtwo || [ "$A" ];do
L="$L $A"
R="$R $B"
done < NewFile
echo $L
echo $R
注意:不是将变量存储在字符串$ L和$ R中,而是使用bash数组而不是使用L_ARRAY + =(“$ A”)或者像这样:
#!/bin/bash
L=()
R=()
while read A && read B && read dummy && read dumtwo || [ "$A" ];do
L[${#L[@]}]=${A}
R[${#R[@]}]=${B}
done < NewFile
echo -e "${L[@]}\n${R[@]}"
或使用sed(2个电话)
L=`sed -n 1~4p NewFile`
R=`sed -n 2~4p NewFile`
echo $L
echo $R