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

时间:2016-08-05 05:18:01

标签: linux bash csv awk sed

我有一个input.csv文件,其中第2列和第3列具有可变的lengtt。

100,Short Column, 199
200,Meeedium Column,1254
300,Loooooooooooong Column,35

我尝试使用以下命令来实现干净的制表,但我需要在第二列填充一定数量的空格以获得固定的长度列(让我们说总长度为30就足够了。

awk -F, '{print $1 "\t" $2 "\t" $3;}' input.csv

我目前的输出如下:

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命令的任何好主意吗? 谢谢大家。

3 个答案:

答案 0 :(得分:2)

awk

中使用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删除它并使用C样式printf格式化。

答案 1 :(得分:1)

不是选择一些任意数字作为每个字段的宽度,而是采用2遍方法,其中第一遍计算每个字段的最大长度,第二遍打印宽度大小加上几个空格的字段字段:

$ 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 file1
100000,Short Column, 199,a
100,Now is the Winter of our discontent with fixed width fields,20000,b
100,Short Column, 199,c
200,Meeedium Column,1254,d
300,Loooooooooooong Column,35,e

$ awk -f tst.awk file1 file1
100000  Short Column                                                   199  a
   100  Now is the Winter of our discontent with fixed width fields  20000  b
   100  Short Column                                                   199  c
   200  Meeedium Column                                               1254  d
   300  Loooooooooooong Column                                          35  e

答案 2 :(得分:0)

使用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