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?

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.