次のデータがあります。
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,