AWK打印不正确

时间:2014-07-09 05:54:58

标签: awk

这就是我需要做的事情..

我有一个文本文件并使用awk解析它。输出应为json格式。它应该是这样的:

{
"Record X" : { "Key1":"Value1", "Key2":"Value2"},
"Record Y" : { "Key1":"Value1", "Key2":"Value2"},
"Record Z" : { "Key1":"Value1", "Key2":"Value2"},
"Record A" : { "Key1":"Value1", "Key2":"Value2"}
}

现在,这就是textfile的内容:

Record X
   Key1 is Value1, Key2 is Value2
Record Y
   Key1 is Value1, Key2 is Value2
Record Z
   Key1 is Value1, Key2 is Value2
Record A
   Key1 is Value1, Key2 is Value2

我尝试创建一个脚本来生成我想要的输出,我在第一部分,但我已经坚持打印线。这是我的剧本:

 awk 
'BEGIN { print "{" }
      { if($0 ~ /^Record /){print "\"" $0 "\":" }}
 END  { print "}" }' myRecord.txt

输出就是这个..

{
":ecord X
":ecord Y
":ecord Z
":ecord A
}

我不明白为什么那种脚本会产生类似的东西。 请告诉我什么是错的。谢谢!

4 个答案:

答案 0 :(得分:1)

这是另一个awk而不使用getline

awk -F"[ ,]*" 'BEGIN {print "{"} /^Record/ {a=$0;next} {print "\""a"\" : { \""$2"\":\""$4"\", \""$5"\":\""$7"\"},"} END {print "}"}'
{
"Record X" : { "Key1":"Value1", "Key2":"Value2"},
"Record Y" : { "Key1":"Value1", "Key2":"Value2"},
"Record Z" : { "Key1":"Value1", "Key2":"Value2"},
"Record A" : { "Key1":"Value1", "Key2":"Value2"},
}

如果您在上次,遇到问题,可以这样做:

awk -F"[ ,]*" -v f=$(cat file | wc -l) 'BEGIN {print "{"} /^Record/ {a=$0;next} {print "\""a"\" : { \""$2"\":\""$4"\", \""$5"\":\""$7"\"}"(NR==f?"":",")} END {print "}"}' file
{
"Record X" : { "Key1":"Value1", "Key2":"Value2"},
"Record Y" : { "Key1":"Value1", "Key2":"Value2"},
"Record Z" : { "Key1":"Value1", "Key2":"Value2"},
"Record A" : { "Key1":"Value1", "Key2":"Value2"}
}

或全部只在awk

awk -F"[ ,]*" 'BEGIN {print "{"} FNR==NR {f=NR;next} /^Record/ {a=$0;next} {print "\""a"\" : { \""$2"\":\""$4"\", \""$5"\":\""$7"\"}"(FNR==f?"":",")} END {print "}"}' file{,}
{
"Record X" : { "Key1":"Value1", "Key2":"Value2"},
"Record Y" : { "Key1":"Value1", "Key2":"Value2"},
"Record Z" : { "Key1":"Value1", "Key2":"Value2"},
"Record A" : { "Key1":"Value1", "Key2":"Value2"}
}

答案 1 :(得分:0)

你可以通过awk的getline函数

来完成
$ awk 'BEGIN{printf "{\n"}/^Record/{var=$0; getline; w=$1; x=$3; y=$4; z=$6;}{printf "\""var"\"" " : { ""\""w"\""":\""x"\", \""y"\":\""z"\"},\n"} END{printf "}\n"}' file
{
"Record X" : { "Key1":"Value1,", "Key2":"Value2"},
"Record Y" : { "Key1":"Value1,", "Key2":"Value2"},
"Record Z" : { "Key1":"Value1,", "Key2":"Value2"},
"Record A" : { "Key1":"Value1,", "Key2":"Value2"},
}

通过GNU awk的gsub函数,

$ awk -v RS="Record" 'BEGIN{print "{"} gsub(/\n/,"",$0){gsub(/.$/,"",$4); print "\""RS" "$1"\" : { \""$2"\":\""$4"\", \""$5"\":\""$7"\"},"} END{print "}"}' file
{
"Record X" : { "Key1":"Value1", "Key2":"Value2"},
"Record Y" : { "Key1":"Value1", "Key2":"Value2"},
"Record Z" : { "Key1":"Value1", "Key2":"Value2"},
"Record A" : { "Key1":"Value1", "Key2":"Value2"},
}

答案 2 :(得分:0)

使用您的流逻辑:

 awk 'BEGIN { print "{" }
        /^Record /{
            if (c){printf ",\n"}
            printf("\"%s\":",$0);next}
            {
            gsub("is",":")
            gsub("  *","\"")
            printf(" {%s\"}",$0)
            c++
            }
        END  { print "\n}" }'  infile

答案 3 :(得分:0)

您的主要问题是您的输入文件是在Windows上创建的,因此每行末尾的control-Ms会在打印行时导致损坏。在运行脚本之前,使用dos2unix或类似的方法删除它们。不要使用下面建议的任何getline解决方案,因为这是错误的方法,并引入了很多警告和复杂性(参见http://awk.info/?tip/getline)。

试试这个:

$ cat tst.awk
BEGIN{ print "{" }
NR%2 { id = $0; next }
{
    sub(/^ +/,"")
    gsub(/ is /,"\":\"")
    gsub(/, /,"\", \"")
    printf "%s\"%s\" : { \"%s\"}", (c++?",\n":""), id, $0
}
END{ print "\n}" }

$ awk -f tst.awk file
{
"Record X" : { "Key1":"Value1", "Key2":"Value2"},
"Record Y" : { "Key1":"Value1", "Key2":"Value2"},
"Record Z" : { "Key1":"Value1", "Key2":"Value2"},
"Record A" : { "Key1":"Value1", "Key2":"Value2"}
}