gpt4 book ai didi

shell - 使用awk输出csv2md格式

转载 作者:行者123 更新时间:2023-12-04 13:07:27 28 4
gpt4 key购买 nike

我需要使用 awk 创建一个 Markdown 格式的输出,这类似于我们使用 mysql 获得的表结果。换句话说,我试图模仿 https://www.convertcsv.com/csv-to-markdown.htm使用以下输入。

id|type|cost|date|ship
0|A|223|201603|PORT
0|A|22|201602|PORT
0|A|422|201601|DOCK
1|B|3213|201602|DOCK
1|B|3213|201601|PORT
2|C|2321|201601|DOCK

我正在寻找的输出如下

------------------------------
|id |type |cost | date |ship |
------------------------------
|0 |A |223 |201603 |PORT |
|0 |A |22 |201602 |PORT |
|0 |A |422 |201601 |DOCK |
|1 |B |3213 |201602 |DOCK |
|1 |B |3213 |201601 |PORT |
|2 |C |2321 |201601 |DOCK |
------------------------------

我的第一个尝试是获取每列的最大大小,并在打印时将其用于格式设置。但是下面的那个没有按预期工作。

awk -F"|" ' 
NR==1 { hdr=$0; for(i=1;i<=NF;i++) { a[i]=length($i) } next }
{ for(i=1;i<=NF;i++) { ;a[i]=length($i)>a[i]?length($i):a[i] } content[NR]=$0 }
END {
for(i in a) len+=a[i]+2;
$0=""; OFS="-"; len++; NF=len; print ;
n=split(hdr,arr,FS);
for(i=1;i<=n;i++)
{ printf("%6s |",arr[i]); } # instead of 6 i want to pass a[i] ==> "%6" a[i] "s |" is not working
print "";

}
' data.txt

如何修复它并获得所需的输出。

最佳答案

这需要一个 2-pass 方法,以下任一方法都可以:

A) 读取输入文件两次,因此它使用的内存非常少:

$ cat tst.awk
BEGIN { FS=OFS="|" }
NR==FNR {
for (i=1; i<=NF; i++) {
wid = length($i)
wids[i] = (wid > wids[i] ? wid : wids[i])
}
next
}
FNR==1 {
totWid = NF+1
for (i=1; i<=NF; i++) {
totWid += wids[i]
}
dashes = sprintf("%*s",totWid,"")
gsub(/ /,"-",dashes)
print dashes
printf "%s", OFS
for (i=1; i<=NF; i++) {
printf "%*s%s", wids[i], $i, OFS
}
print ""
print dashes
next
}
{
printf "%s", OFS
for (i=1; i<=NF; i++) {
printf "%-*s%s", wids[i], $i, OFS
}
print ""
}
END { print dashes }

$ awk -f tst.awk file file
--------------------------
|id|type|cost| date|ship|
--------------------------
|0 |A |223 |201603|PORT|
|0 |A |22 |201602|PORT|
|0 |A |422 |201601|DOCK|
|1 |B |3213|201602|DOCK|
|1 |B |3213|201601|PORT|
|2 |C |2321|201601|DOCK|
--------------------------

B) 将整个文件存储在内存中,然后第二遍是数组遍历而不是再次读取文件,如果你有足够的内存来执行它应该会运行得更快:

$ cat tst.awk
BEGIN { FS=OFS="|" }
{
for (i=1; i<=NF; i++) {
wid = length($i)
wids[i] = (wid > wids[i] ? wid : wids[i])
vals[NR,i] = $i
}
}
END {
totWid = NF+1
for (i=1; i<=NF; i++) {
totWid += wids[i]
}
dashes = sprintf("%*s",totWid,"")
gsub(/ /,"-",dashes)
print dashes
printf "%s", OFS
for (i=1; i<=NF; i++) {
printf "%*s%s", wids[i], vals[1,i], OFS
}
print ""
print dashes

for (lineNr=2; lineNr<=NR; lineNr++) {
printf "%s", OFS
for (i=1; i<=NF; i++) {
printf "%-*s%s", wids[i], vals[lineNr,i], OFS
}
print ""
}
print dashes
}

$ awk -f tst.awk file
--------------------------
|id|type|cost| date|ship|
--------------------------
|0 |A |223 |201603|PORT|
|0 |A |22 |201602|PORT|
|0 |A |422 |201601|DOCK|
|1 |B |3213|201602|DOCK|
|1 |B |3213|201601|PORT|
|2 |C |2321|201601|DOCK|
--------------------------

关于shell - 使用awk输出csv2md格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68745005/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com