空の行が見つかったら新しい列に変更[重複]

空の行が見つかったら新しい列に変更[重複]

次のデータがあります。

q   
w   
e  

e   
r   
r
t   

23    
21   
1    

空の行が見つかるたびに、それを新しい列に変更します。

出力

q,e,23    
w,r,21
e,r,1
,t,

私はそれを試しましたが、sedを使用して行を変更することはできません。これを達成する方法を教えてください。

答え1

awkをお勧めします。行区切り文字を空白行に設定し、その行を変数として収集できます。最後に、収集された変数を表示できます。

このような:

awk 'BEGIN{RS="\n\n";}{A=(A","$1);B=(B","$2);C=(C","$3);D=(D","$4)}END{print A;print B;print C;print D}' input.txt |sed s/'^,'//

しかし、原則は残っています。実際にはテーブル転置です。

答え2

1つのオプションは、すべての改行をカンマに変更し(最終的にCSVを望むようです)、二重コンマを改行に置き換えて重複するスペースを削除することです。最後に、結果は次のように変わりますdatamash

tr '\n' ',' < input.dat  |
  sed 's/,,/\n/g' |
  tr -d ' ' |
  datamash --no-strict --filler='' -t ',' transpose

答え3

実際の多次元配列と「結合」機能を外部ライブラリとして含むGNU awkの使用:

gawk '
    @include "join"
    BEGIN {row=0; col=0}
    NF == 0 {col++; row=0; next}
    {data[row][col] = $1; row++}
    END {
        PROCINFO["sorted_in"] = "@ind_num_asc"
        for (r in data)
            print join(data[r], 0, col, ",")
    }
' file

出力

q,e,23
w,r,21
e,r,1
,t,

答え4

$ cat tst.awk
BEGIN {
    OFS = ","
    numCols = 1
}
!NF {
    rowNr = 0
    ++numCols
    next
}
{
    vals[++rowNr,numCols] = $0
    numRows = (rowNr > numRows ? rowNr : numRows)
}
END {
    for (rowNr=1; rowNr<=numRows; rowNr++) {
        for (colNr=1; colNr<=numCols; colNr++) {
            printf "%s%s", vals[rowNr,colNr], (colNr<numCols ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk file
q,e,23
w,r,21
e,r,1
,t,

関連情報