0

This is abc.txt file

NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"
NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"

Need a output in below format with abc.csv

NAME    StartTime   TotalElapsedTime    Pool    ThreadsReached
MARK    14:11:26.710583     0       10      0
MARK    14:11:26.710583     0       10      0
1
  • Where are the commas for the csv?
    – Jeff Schaller
    Commented May 19, 2017 at 19:12

2 Answers 2

1

As basic CSV format assumes comma , as field separator use the following GNU sed approach:

sed -e '1iNAME,StartTime,TotalElapsedTime,Pool,ThreadsReached' -e 's/[^=]*="\([^"]*\)"/\1,/g; s/,$//g' file

The output:

NAME,StartTime,TotalElapsedTime,Pool,ThreadsReached
MARK,14:11:26.710583,0,10,0
MARK,14:11:26.710583,0,10,0

1i - inserts header line before the first line of the file

s/[^=]*="\([^"]*\)"/\1,/g - extracting all attribute values

0
while IFS= read -r l; do
   set -f; IFS==; set -- $l; shift; N=$#
   for arg
   do
      set -- ${1+"$@"} "$(expr " $arg" : ' "\(.*\)"')"
   done
   shift "$N"; IFS=,; echo "$*"
done < abc.txt

while IFS= read -r l; do
   set -f; IFS==; set -- $l; shift
   while case ${#} in 1 ) break ;; esac; do
      expr " $1" : ' "\(.*\)"'
      shift
   done | tr \\n ,; expr " $*" : '.*"\(.*\)"'
done < abc.txt

perl -lne '$,=",";
   print /(?:^|\h)\K[^=]*/g if $. == 1;
   print /="([^"]*)"/g;
' abc.txt

Explanations

  • In the Perl code, from the first line we extract the field names via the regex /(?:^|\h)\K[^=]*/g which is read as get me the run of non= characters on whose left is seen either a horizontal whitespace \h or beginning of line ^. Then these are printed using the OFS $, set to a comma.
  • For all lines (including the first as well), we extract the field values via the regex /="([^"]*)"/g which is to be read as extract the string enclosed with a double quote values (assuming no escaped double quotes) which are adjacent to an equals sign on it's left. The collection of these values are then taken to stdout joined with the OFS.
  • In the case of the while loop solution, we first read in the line as is with no word splitting. Then we set the IFS to an = and reject the first field. Now all the fields will have the format "..."... We then use the expr utility to flesh out the value within double quotes and place them on the $@ array. At the end of the for loop we remove the original elements ($N) then what remains is what we want. Finally they are joined together by the comma by means of setting IFS to comma and expanding $*.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .