4

I have a file that contains text as follows:

dt=2016-06-30,path=path1,site=US,mobile=1
dt=2016-06-21,path=path2,site=UK,mobile=0

I want to convert it to text with double-quoted values in the key-value pairs, like so:

dt="2016-06-30",path="path1",site="US",mobile="1"
dt="2016-06-21",path="path2",site="UK",mobile="0"

How can I place every value within double quotes, using Sed or any other command?

4 Answers4

7

Using Sed

sed -e 's/=\([^,]*\)/="\1"/g' file.txt

Using Awk

awk -F, -v OFS=, '{for (f=1;f<=NF;f++) {sub(/=/,"&\"",$f); sub(/$/,"\"",$f)}; print}' file.txt

Or, shorter:

awk -F, -v OFS=, '{for (f=1;f<=NF;f++) {gsub(/=|$/,"&\"",$f)} print}' file.txt 

Shorter still:

awk -F, -v OFS=, '{for (f=1;f<=NF;f++) {gsub(/=|$/,"&\"",$f)}} 1' file.txt 

Using ex

Ex is designed for file editing, but you can preview changes without actually saving them back to the file like so:

ex -sc '%s/=\([^,]*\)/="\1"/g | %p | q!' file.txt 

To actually make the changes and save them to the file, use:

ex -sc '%s/=\([^,]*\)/="\1"/g | x' file.txt

However if you give a pattern which is found nowhere in the file (e.g. there is no = anywhere in the file) then Ex will not exit automatically. Thus for better robustness I usually use printf to pass commands to Ex:

printf '%s\n' '%s/=\([^,]*\)/="\1"/g' %p | ex file.txt

And to save changes:

printf '%s\n' '%s/=\([^,]*\)/="\1"/g' x | ex file.txt
Wildcard
  • 36,499
4

With perl

$ # unlike sed/awk, newline is still part of input record
$ perl -pe 's/=\K[^,\n]*/"$&"/g' ip.txt 
dt="2016-06-30",path="path1",site="US",mobile="1"
dt="2016-06-21",path="path2",site="UK",mobile="0"

$ # or chomp newline and add it back while printing
$ perl -lpe 's/=\K[^,]+/"$&"/g' ip.txt
dt="2016-06-30",path="path1",site="US",mobile="1"
dt="2016-06-21",path="path2",site="UK",mobile="0"
Sundeep
  • 12,008
  • You don't need to have a newline in the bracket expression. the characters from the last = to end of line are already non-comma characters. – glenn jackman Nov 10 '16 at 14:05
  • @glennjackman it is treating newline as non-comma character for me.. perl v5.22.1.. with -l option it won't be needed as you put it – Sundeep Nov 11 '16 at 15:22
3

Using awk

awk '{gsub(/=/, "=\""); gsub(/,/,"\","); print $0"\""}' < file.txt
0

Using Miller:

$ mlr put 'for (k,v in $*) {$[k] = "\"".v."\""}' mobile.dat
dt="2016-06-30",path="path1",site="US",mobile="1"
dt="2016-06-21",path="path2",site="UK",mobile="0"
John Kerl
  • 186
  • 5