将列转置为数据行

时间:2016-06-28 20:35:50

标签: regex bash transpose

我的项目超出了我的技能。我的最终目标是将处理后的数据转换为散点图。为此,我需要转换此格式的日志输出:

        Counter Name     Port: 1/8/x1     Port: 1/8/x2     Port: 1/8/x3     Port: 1/8/x4
  ================== ================ ================ ================ ================
         IfInOctets:          5470343          5520353          5628425          5685539
      IfInUcastPkts:             8878             9029             9345             9512
     IfInNUcastPkts:            17779            17755            17755            17755
       IfInPktDrops:                0                0                0                0
       IfInDiscards:            26657            26784            27100            27267
         IfInErrors:                0                0                0                0

Port number,IfInErrors 

值。

为了减少不必要的标签,我迭代地使用awk和其他命令。

for i in `ls *.log`; do 
    awk '/Counter Name|IfInDiscards/ {print $0}' $i.txt
done

(我的技能等级是“muypequeña”。命令是:

for i in `ls *.log`; do 
    awk '/Counter Name|IfInDiscards/ {print $0}' $i.txt
done

我接下来使用sed

丢弃不需要的数据
sed -i 's/Counter Name//g' *.txt    #Delete Counter name and IfInDiscards
sed -i 's/IfInErrors://g'  *.txt
sed -i 's/Port: //g'                #Eliminate unnecessary Port: and space
sed -i 's/  */ /g' 
sed -i "s/ /,/g"                    #Convert white space to commas

这给我留下了干净的柱状数据。

  Column1,column2,Column3,Column4,Column5
Row1 ,1/8/x1,1/8/x2,1/8/x3,1/8/x4
Rowd2 ,0,0,0,0

所以,我的下一个项目是删除前导逗号(Column1)。

  Column1,column2,Column3,Column4
Row1  1/8/x1,1/8/x2,1/8/x3,1/8/x4
Row2  0,0,0,0

然后对我来说重要的是将数据转换为这种格式(连接列+行数据,命令和列+行数据)。

Col1+row1,col1+row2
Col2+row1,col2+row2

。 。 端

总会有四列,最多100行。

摩擦是我不知道如何将其转换为代码。

与往常一样,我不只是在寻找一个简单的“有人能为我做这个”的方法,因为我想建立自己的技能水平。复制+粘贴很快,但我不学习。

话虽如此,我正在寻求指导。

1 个答案:

答案 0 :(得分:1)

这可以在一个awk命令中完成。使用数组来保存第一行的端口号。

for file in *.log; do
    awk '/Counter Name/ { for (col = 4; col <= NF; col += 2) port[col/2] = $col }
         /IfInErrors/ { for (col = 2; col <= NF; col++) printf("%s,%d\n", port[col], $col) }' < "$file"
done

awk脚本的第一行与具有端口号标题的行匹配。循环遍历列2,并创建一个包含端口号的数组。

第二行与包含输入错误值的行匹配。然后它会遍历其余列,从上面的数组中打印端口号,然后是该列中的值。

如果您希望能够将多行值转换为列,则需要使用数组来保存所有值,而不是在看到所需的计数器时立即打印。

    awk '/Counter Name/ { for (col = 4; col <= NF; col += 2) port[col/2] = $col; maxcols = NF/2 }
         /IfInErrors/ { for (col = 2; col <= NF; col++) inErrors[col] = $col }
         /IfInOctets/ { for (col = 2; col <= NF; col++) inOctets[col] = $col }
        END { for ( col = 2; col <= maxcols; col++) printf("%s,%d,%d\n", port[col], inErrors[col], inOctets[col]); }
    ' < "$file"
done

您可以为要包含在输出中的每个值重复/IfInErrors//IfInOctets/等行。更改保存值的数组的名称,并将其添加到printf块中的END