Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何使用awk或sed调整bash中列字段的长度?_Linux_Bash_Csv_Awk_Sed - Fatal编程技术网

Linux 如何使用awk或sed调整bash中列字段的长度?

Linux 如何使用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

我有一个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   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]/)。再次感谢你,一些代码!当然,只需添加一个点即可