Linux 如何使用awk或sed调整bash中列字段的长度?
我有一个input.csv文件,其中第2列和第3列有变量lengttLinux 如何使用awk或sed调整bash中列字段的长度?,linux,bash,csv,awk,sed,Linux,Bash,Csv,Awk,Sed,我有一个input.csv文件,其中第2列和第3列有变量lengtt 100,Short Column, 199 200,Meeedium Column,1254 300,Loooooooooooong Column,35 我试图使用下面的命令来实现一个干净的表格,但是我需要用一定数量的空格填充第二列,以获得一个固定长度的列(假设总长度为30就足够了) 我当前的输出如下所示: 100 Short Column 199 200 Meeedium Column 1254 300
100,Short Column, 199
200,Meeedium Column,1254
300,Loooooooooooong Column,35
我试图使用下面的命令来实现一个干净的表格,但是我需要用一定数量的空格填充第二列,以获得一个固定长度的列(假设总长度为30就足够了)
我当前的输出如下所示:
100 Short Column 199
200 Meeedium Column 1254
300 Loooooooooooong Column 35
我希望通过正确填写第2列和第3列,实现以下输出:
100 Short Column 199
200 Meeedium Column 1254
300 Loooooooooooong Column 35
关于awk或sed命令有什么好主意吗?
谢谢大家。用于awk
$ awk -F, '{gsub(/ /, "", $3); printf "%-5s %-25s%5s\n", $1, $2, $3}' file input.csv
100 Short Column 199
200 Meeedium Column 1254
300 Loooooooooooong Column 35
我在上面所做的是将IFS
,字段分隔符设置为,
;由于文件仅在第3列中有一些空格,因此会损坏printf
处理字符串的方式,使用gsub
将其删除,并在awk
中使用C样式printf格式
$ awk -F, '{gsub(/ /, "", $3); printf "%-5s %-25s%5s\n", $1, $2, $3}' file input.csv
100 Short Column 199
200 Meeedium Column 1254
300 Loooooooooooong Column 35
我在上面所做的是将IFS
,字段分隔符设置为,
;由于文件仅在第3列中有一些空格,因此它会破坏printf
处理字符串的方式,使用gsub
将其删除,并使用printf
以C风格格式化
$ perl -pe 's/([^,]+),([^,]+),([^,]+)/sprintf "%-6s%-30s%5s", $1,$2,$3/e' input.csv
100 Short Column 199
200 Meeedium Column 1254
300 Loooooooooooong Column 35
使用perl的解决方案
$ perl -pe 's/([^,]+),([^,]+),([^,]+)/sprintf "%-6s%-30s%5s", $1,$2,$3/e' input.csv
100 Short Column 199
200 Meeedium Column 1254
300 Loooooooooooong Column 35
不要选择任意数字作为每个字段的宽度,而是采用两次通过的方法,第一次通过计算每个字段的最大长度,第二次通过在字段之间加上两个空格的宽度打印字段:
$ cat tst.awk
BEGIN { FS=" *, *"; OFS=" " }
NR==FNR {
for (i=1;i<=NF;i++) {
w[i] = (length($i) > w[i] ? length($i) : w[i])
if ($i ~ /[^0-9]/) {
a[i] = "-"
}
}
next
}
{
for (i=1;i<=NF;i++) {
printf "%"a[i]w[i]"s%s", $i, (i<NF ? OFS : ORS)
}
}
$ awk -f tst.awk file file
100 Short Column 199
200 Meeedium Column 1254
300 Loooooooooooong Column 35
不要选择任意数字作为每个字段的宽度,而是采用两次通过的方法,第一次通过计算每个字段的最大长度,第二次通过在字段之间加上两个空格的宽度打印字段:
$ cat tst.awk
BEGIN { FS=" *, *"; OFS=" " }
NR==FNR {
for (i=1;i<=NF;i++) {
w[i] = (length($i) > w[i] ? length($i) : w[i])
if ($i ~ /[^0-9]/) {
a[i] = "-"
}
}
next
}
{
for (i=1;i<=NF;i++) {
printf "%"a[i]w[i]"s%s", $i, (i<NF ? OFS : ORS)
}
}
$ awk -f tst.awk file file
100 Short Column 199
200 Meeedium Column 1254
300 Loooooooooooong Column 35
column-t input.csv
或查看printf
或awk
的printf
column-s,-t文件应该可以it@anubhava:谢谢。@fedorqui FIELDWIDTHS是用来阅读的,不是用来写作的,它对阅读没有帮助。@EdMorton很好。注意,谢谢。column-t input.csv
或查看printf
或awk
的printf
column-s,-t文件应该可以it@anubhava:谢谢。@fedorqui FIELDWIDTHS是用来阅读的,不是用来写作的,它对阅读没有帮助。@EdMorton很好。注意,谢谢。或者使用bash的printf:whileifs=,read-rabc;打印“%5s%-25s%5s\n”“a”“b”“c”;完成
@i一个好代码!非常感谢。有没有办法自定义awk,以便只对某些特定列进行对齐?例如:在一个包含30列的csv中,我只希望将对齐方式应用于第20、21、22列(因为第1至19列和第23至30列只是我希望从打印中丢弃的页眉/页脚)。或者使用bash的printf:而IFS=,read-r a b c;打印“%5s%-25s%5s\n”“a”“b”“c”;完成
@i一个好代码!非常感谢。有没有办法自定义awk,以便只对某些特定列进行对齐?例如:在一个包含30列的csv中,我只希望将对齐方式应用于第20、21、22列(因为第1至19列和第23至30列只是我希望从打印中丢弃的页眉/页脚)。绝妙的解决方案。有没有办法自定义tst.awk(或bash中的命令行),以便只对某些特定列进行对齐?例如:在一个包含30列的csv中,我只希望将对齐方式应用于第20、21、22列(因为从1到19列只是我希望从打印中丢弃的标题)。当然,只需将1
更改为起始字段号,将NF
更改为结束字段号。如果愿意,将带有设置为-v
的变量的开始/结束值传入。尝试一下,如果你想不出来,就发一个新的后续问题。但是,如果您在帖子中得到了此问题的答案,请记住通过单击旁边的复选标记(请参阅)接受您选择的答案。感谢您的提示,此脚本工作正常!我想知道是否有任何方法可以修改tst.awk脚本以获得数字字段的正确对齐,同样在一些小数的情况下,目前,脚本将数字字段的数量1000对齐在右侧,而1000.99对齐在左侧(实际上这是我的错误,我在问题中没有指定数字字段包含小数)。也许我应该在您的行中添加一些代码,开头是:if($I~/[^0-9]/)。再次感谢你,一些代码!当然,只需添加一个点[^0-9.]
。不客气,很好的解决方案。有没有办法自定义tst.awk(或bash中的命令行),以便只对某些特定列进行对齐?例如:在一个包含30列的csv中,我只希望将对齐方式应用于第20、21、22列(因为从1到19列只是我希望从打印中丢弃的标题)。当然,只需将1
更改为起始字段号,将NF
更改为结束字段号。如果愿意,将带有设置为-v
的变量的开始/结束值传入。尝试一下,如果你想不出来,就发一个新的后续问题。但是,如果您在帖子中得到了此问题的答案,请记住通过单击旁边的复选标记(请参阅)接受您选择的答案。感谢您的提示,此脚本工作正常!我想知道是否有任何方法可以修改tst.awk脚本以获得数字字段的正确对齐,同样在一些小数的情况下,目前,脚本将数字字段的数量1000对齐在右侧,而1000.99对齐在左侧(实际上这是我的错误,我在问题中没有指定数字字段包含小数)。也许我应该在您的行中添加一些代码,开头是:if($I~/[^0-9]/)。再次感谢你,一些代码!当然,只需添加一个点即可