在awk中操纵列

时间:2013-08-28 15:47:28

标签: unix awk grep

我想操纵一些颜色以更好地将一些数据表示为图形。 到目前为止,我所有的数据都是这样排列的,第一行是标题,然后是接下来的两行持有x,然后是该数据的y数据。文件中的所有数字都由一个标签分隔。像这样:

200.023 468.865 567.976 647.711    ##this line is the 'header'
59.927  58.099  60.546  61.461     ##this line is x data
1576.77 2192.02 1630.22 1879.04    ##this line is y data
59.769  59.300  60.380  61.308     ##next x
1111.36 2674.2  1590.89 970.134    ##next y
##numbers continue down, and across the page

我想取y坐标(第1列第3行)并将其放在与制表符分隔的x(第2行第2行)相同的行中,因此该行现在将是两倍长。因此标题行不会出现位置我想我应该添加一些容易识别的东西,比如'“space”/ t',但是任何东西都可以。 输出:

200.023 space   468.865 space   567.976 space   647.711 space
59.927  1576.77 58.099  2192.02 60.546  1630.22 61.461  1879.04
59.769  1111.36 59.300  2674.2  60.380  1590.89 61.308  970.134

如果我澄清任何事情,请告诉我。 感谢

3 个答案:

答案 0 :(得分:3)

这需要一个脚本:

$ cat preprocess.awk 
BEGIN {                       # Before processing the file set OFS
    OFS="\t"                  # Set the Output Field Separator to a TAB
}
NR == 1 {                     # Process the header
    for (i=1;i<=NF;i++)       # Loop over every field in the header
        $i=$i OFS             # Add a second TAB to space headers correctly
    print $0                  # Print the header
    next                      # Get the next line in the file
}
NR % 2 {                      # For all the odd lines in the file (y lines)
    line = sep = ""           # Clear the line and separator variables
    for (i=1;i<=NF;i++) {     # Loop over the y value
        line = line sep x[i] OFS $i  # Concatenate x and y values
        sep = OFS             # Set after to avoid leading TAB
    }
    print line                # Print the line
    next                      # Get the next line in the file
}
{                             # If here then we are looking at the even lines (x)
    for (i=1;i<=NF;i++)       # Loop over the x values
        x[i] = $i             # Store values in array x
}

这会将标题与两个标签分开,并在连续的行中收集所有xy对。

用法:

使用以下输入:

$ cat file
h1 h2 h3 h4
x1 x2 x3 x4
y1 y2 y3 y4
x5 x6 x7 x8
y5 y6 y7 y8
x9 x10 x11 x12
y9 y10 y11 y12

产地:

$ awk -f preprocess.awk file 
h1      h2      h3      h4  
x1  y1  x2  y2  x3  y3  x4  y4
x5  y5  x6  y6  x7  y7  x8  y8
x9  y9  x10 y10 x11 y11 x12 y12

答案 1 :(得分:2)

如果标题在整个文件中重复,那么这可能有效:

#!/usr/bin/awk -f

{
    m = NR % 5
    for (i = 1; i <= 4; ++i) {
        a[m, i] = $i
    }
}
m == 0 {
    printf("%8s %8s %8s %8s %8s %8s %8s %8s\n", "" a[1, 1], "space", a[1, 2], "space", a[1, 3], "space", a[1, 4], "space")
    printf("%8s %8s %8s %8s %8s %8s %8s %8s\n", a[2, 1], a[3, 1], a[2, 2], a[3, 2], a[2, 3], a[3, 3], a[2, 4], a[3, 4])
    printf("%8s %8s %8s %8s %8s %8s %8s %8s\n", a[4, 1], a[0, 1], a[4, 2], a[0, 2], a[4, 3], a[0, 3], a[4, 4], a[0, 4])
}

会打印出来:

 200.023    space  468.865    space  567.976    space  647.711    space
  59.927  1576.77   58.099  2192.02   60.546  1630.22   61.461  1879.04
  59.769  1111.36   59.300   2674.2   60.380  1590.89   61.308  970.134

我确实按字面意思放置了"space",但你可以用""替换它们。

答案 2 :(得分:1)

这是一个awk单行:

$ awk 'NR==1{gsub("\t","\tspace\t");print;next}!(NR%2){split($0,a,"\t")}NR%2{for (i=1;i<=NF;i++) printf "%s\t%s\t", a[i], $i;print ""} ' file 
200.03  space   468.865 space   567.976 space   647.711
59.927  1576.77 58.099  2192.02 60.546  1630.22 61.461  1879.04 
59.769  1111.36 59.300  2674.2  60.380  1590.89 61.308  970.134 

或者以更易读的格式:

$ awk '
    NR==1{
        gsub("\t","\tspace\t")
        print
        next
    }
    !(NR%2){
        split($0,a,"\t")
    }
    NR%2{
        for (i=1;i<=NF;i++) 
            printf "%s\t%s\t", a[i], $i
            print ""
    } ' file