user3714598
user3714598

Reputation: 1773

AWK not printing properly

This is what I need to do..

I have a textfile and parse it using awk. The output should be in json format. It should look like this:

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

Now, this is how the content of textfile looks like:

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

I tried creating a script to produce the output that I want, I'm in the first part however Im already stuck with printing the line. This is my script:

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

And the output is this..

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

I do not understand why that kind of script will produce something like that. Kindly tell me what's wrong. thank you!

Upvotes: 0

Views: 156

Answers (4)

Ed Morton
Ed Morton

Reputation: 203189

Your main problem is that your input file was created on Windows and so has control-Ms at the end of each line causing corruption when printing the lines. Remove them with dos2unix or similar before running your script. Do NOT use any getline solution suggested below as that would be the wrong approach and introduce a lot of caveats and complexity (see http://awk.info/?tip/getline).

Try this:

$ 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"}
}

Upvotes: 0

Avinash Raj
Avinash Raj

Reputation: 174696

You could do this through awk's getline function,

$ 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"},
}

Through GNU awk's gsub function,

$ 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"},
}

Upvotes: 0

Juan Diego Godoy Robles
Juan Diego Godoy Robles

Reputation: 14945

Using your flow logic:

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

Upvotes: 0

Jotne
Jotne

Reputation: 41446

Here is another awk without using 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"},
}

If you get problems with last , you can do like this:

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"}
}

Or all in only 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"}
}

Upvotes: 1

Related Questions