2

I have a string in the format `foo="is a first one" foo1="is a second one" foo3="is a third one" and many fields like the said pattern. I want to parse this and have o/p as

foo              foo1              foo3
is a first one   is a second one   is a third one

Any help is greatly appreciated.

6
  • What have you already tried? Where have you already researched on this task? Did you encounter any problems? Commented Apr 26, 2011 at 5:43
  • I tried this with awk using FS commadn but didn't succed Commented Apr 26, 2011 at 7:14
  • Since you already tried awk, I'd recommend you move to perl rather than do this in the shell. It's quite simple there. Commented Apr 26, 2011 at 8:11
  • @Noufal, he probably hadn't tried hard enough. Awk is perfectly fine to do string parsing as Perl. Commented Apr 26, 2011 at 11:08
  • Probably but as time goes by, perl is generally more capable than awk in my experience. Commented Apr 26, 2011 at 11:22

4 Answers 4

2

Columnizing the output is the hard part. (I would agree with Noufal here that perl is a good way to go.) However, it is doable with other more basic tools. For example:

$ cat input
foo
is a first one
foo1
is a second one
foo3
is a third one
$ ( awk 'NR % 2' input; awk 'NR % 2 == 0' input ) | paste - - - | column -s'   ' -t
foo             foo1             foo3
is a first one  is a second one  is a third one

(Note that the -s argument to column should contain a tab between the single quotes.)

Sign up to request clarification or add additional context in comments.

Comments

1

Awk is perfectly fine to do string parsing.

s='foo="is a first one" foo1="is a second one" foo3="is a third one"'
echo $s | awk 'BEGIN{
    FS="\042 "
}
{
    c=NF
    for(i=1;i<=NF;i++){
        m = split($i , a, "=")
        header[i] = a[1]
        content[i]= a[2]
    }
}
END{
    for(i=1;i<=c;i++){
        printf "%s\t", header[i]
    }
    print ""
    for(i=1;i<=c;i++){
        printf "%s\t", content[i]
    }
    print ""
}
'

Comments

0

Is this you wanted ?

   sed -nr 's/" /"\n/g;s/=/\n/gp' <<END  
    > foo="is a first one" foo1="is a second one" foo3="is a third one"
    > END
    foo
    "is a first one"
    foo1
    "is a second one"
    foo3
    "is a third one"

2 Comments

Thanks a lot for the reply. It is working fine.Can you please explain me how it actually works and I also want the command to read input from a file. can you please correct it accordingly. It would be great if I can print data in a tabular form instead of printing it in lines.
i'm so sorry it's too late to reply,but i think you must got the better answer...
0

Stealing the use of column from William's answer, this accepts the OP's suggested input. It requires the values to be double-quoted as per the sample input:

s='foo="is a first one" foo1="is a second one" foo3="is a third one"'
echo "$s" | awk -F'"' '
  {
    for (i=1; i<=NF; i+=2) {
      sub(/^[[:space:]]*/, "", $i)
      sub(/=$/, "", $i)
      vars=vars $i "\t"
    }
    for (i=2; i<=NF; i+=2) {vals=vals $i "\t"}
  }
  END {print vars; print vals}
' | column -t -s $'\t'

outputs

foo             foo1             foo3
is a first one  is a second one  is a third one

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.