Reputation: 1773
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
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
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
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
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