如何打印不可预知的字段 - awk

时间:2015-11-14 06:14:29

标签: awk

我试图通过awk解析下面的输入。 如果只有3对项目意味着如果有ID = 34,ID2 = 35,COL3 =“231,则输出看起来很好。因为我刚刚在printf中使用了4个字符串变量。 但是,项目数(ID / ID2 / COL3)会有所不同。这就是问题所在。

即使没有修复项目的数量,我如何打印所有这些项目?

输入

!{ID=34, ID2=35, COL3="231"}
>
!{ID=99, ID2=23}
>
!{ID=18, ID2=87}
<
@{ID=11, ID2=22, COL3="231",COL4="098", COL5="AAA", COL6="BBB"}
UPD1

awk中

BEGIN { FS="[}{[:space:] ]+"; RS="!|@" }
NR > 1 { 
printf "%s%s%s#%s\n", $2, $3, $4, $5;
}

输出

ID=34,ID2=35,COL3="231"#>
ID=99,ID2=23>#
ID=18,ID2=87<#
ID=11,ID2=22,COL3="231",COL4="098",#COL5="AAA",

期望输出

ID=34,ID2=35,COL3="231"#>
ID=99,ID2=23#>
ID=18,ID2=87#<
ID=11,ID2=22,COL3="231",COL4="098",COL5="AAA",COL6="BBB"#UPD1

第二期望输出

!#ID=34,ID2=35,COL3="231"#>
!#ID=99,ID2=23#>
!#ID=18,ID2=87#<
@#ID=11,ID2=22,COL3="231",COL4="098",COL5="AAA",COL6="BBB"#UPD1

2 个答案:

答案 0 :(得分:2)

我想知道你是否可能会因为有可能以不同的方式看待问题而忙于处理字段,字段分隔符和字段数...

如果您忘记字段和字段数,并说“如果该行包含花括号,删除所有空格,大括号,符号并保存该行,或者使用哈希符号打印保存的行,该怎么办?和当前行“

awk '/{/ {gsub(/[ {}!@]/,"");m=$0;next} {print m"#"$0}' file

ID=34,ID2=35,COL3="231"#>
ID=99,ID2=23#>
ID=18,ID2=87#<
ID=11,ID2=22,COL3="231",COL4="098",COL5="AAA",COL6="BBB"#UPD1

答案 1 :(得分:0)

这是一种非常奇怪的格式。我不得不(重新)安装GNU Awk(4.1.3)来获得你看到的输出。 BSD(Mac OS X)awk无法识别多字符@值中的RS - 请参阅下面的注释。

AFAICT,此代码生成您使用GNU Awk搜索的输出。它在行的最后一个非空白字段前面加上#标记。将OFS设置为空字符串将输出字段之间没有空格的字段。

script.awk

BEGIN   { FS="[}{[:space:]]+"; RS="!|@"; OFS="" }
NR > 1  {
    # printf "%s%s%s#%s\n", $2, $3, $4, $5;
    for (i = NF; i > 1; i--)
    {
        if ($i != "")
        {
            $i = "#" $i
            break
        }
    }
    print
}

示例运行:

$ gawk -f script.awk data
ID=34,ID2=35,COL3="231"#>
ID=99,ID2=23#>
ID=18,ID2=87#<
ID=11,ID2=22,COL3="231",COL4="098",COL5="AAA",COL6="BBB"#UPD1
$

对于相同的数据文件,BSD Awk生成:

$ awk -f script.awk data
ID=34,ID2=35,COL3="231"#>
ID=99,ID2=23#>
ID=18,ID2=87<@ID=11,ID2=22,COL3="231",COL4="098",COL5="AAA",COL6="BBB"#UPD1
$

它会忽略@值中的RS(以及|,但数据并未证明这一点)。但是,根据awk的POSIX规范,这是合法的。

  

<强> RS

     

RS的字符串值的第一个字符应为输入记录分隔符;默认情况下为<newline>。如果RS包含多个字符,则结果未指定。如果RS为null,则记录由包含<newline>加上一个或多个空行的序列分隔,前导或尾随空行不应在输入的开头或结尾处产生空记录,并且{{{无论FS的值是什么,1}}都应始终是字段分隔符。

GNU Awk扩展是一种有效的未指定行为;忽略额外字符的BSD Awk行为也是一种有效的未指定行为。