我有一个数据为:
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
一种选择是用逗号替换所有换行符(因为您似乎最终想要 CSV),然后用换行符替换双逗号并删除重复的空格。最后将结果转置为datamash
:
tr '\n' ',' < input.dat |
sed 's/,,/\n/g' |
tr -d ' ' |
datamash --no-strict --filler='' -t ',' transpose
答案3
使用 GNU awk,它具有真正的多维数组和“join”函数作为外部库:
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,