4

2つの空の行で区切られた単一の列に正または負の浮動小数点値のデータがあります。

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

理想的な状況では、このソリューションは数字だけでなく、同様の方法で区切られたテキストに対しても機能します。

4

6 に答える 6

12

どうですか:

$ 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、出力をフォーマットするために使用されます。

于 2013-03-16T19:01:51.760 に答える
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}2 行目は、PS を保留スペース (HS) にコピーしてから削除します。
  • G他のすべての行では、HS を PS に追加します。
  • s/^(.*)\n(.*)\n(.*)\n(.*)$/\3 \1\n\4 \2/PS を必要な順序に並べ替えます。
  • $!{h;d}最後の行を除くすべての行について、PS を HS にコピーしてから、PS を削除します。これは、最後の行に遭遇すると、PS の内容が出力されることを意味します。
于 2013-03-17T14:18:51.487 に答える
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[*]}
于 2013-03-16T18:53:10.473 に答える
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[*]}"
于 2013-03-16T21:18:59.183 に答える
0

awk への 1 回の呼び出しを使用する:

awk 'BEGIN{RS="\n\n\n"}{A=A " " $1;B=B " " $2}END{printf A "\n" B "\n"}' NewFile

posix シェルのみを使用 (ビルトインを使用)

#!/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 に格納するのではなく、L_ARRAY+=("$A") を使用するか、次のように bash 配列を使用できます。

#!/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
于 2013-03-17T06:54:26.997 に答える
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

これは確かに最善の方法ではありませんが、うまくいきます!

于 2013-03-16T18:41:17.810 に答える