3

I have the following string

y10_zcis y10_nom y10_infl y20_zcis y20_infl y30_zcis

I would like to transform this to

"y10_zcis", "y10_nom", "y10_infl", "y20_zcis", "y20_infl", "y30_zcis"

I accomplished something similar with the extremely ugly:

$ cat in.txt | sed 's/ /\'$'\n/g' | sed 's/\(.*\)/"\1",/g' | tr -d '\n'


"y10_zcis","y10_nom","y10_infl","y20_zcis","y20_infl","y30_zcis",

But that feels like an utter failure, and it doesn't take care of the last unwanted , (but perhaps this is best to just delete afterwards)

5

You can do

sed -e 's| |", "|g' -e 's|^|"|g' -e 's|$|"|g' in.txt

Where

  • 's| |", "|g' will replace every space with ", "
  • 's|^|"|g' while at the beginning there's no space, you must specify with ^ the beginning of the line, so you're telling, put " at the beginning.
  • 's|$|"|g' same thing but specifying the end of every line with $

UPDATE

As @don_crissti pointed out, you can do it shorter with the following

sed 's| |", "|g;s|.*|"&"|'

Where

  • ; separate each instruction
  • .* matches the entire line.
  • & an ampersand on the RHS is replaced by the entire expression matched on the LHS, in this case .*

    RHS=Right hand side

    LHS=Left hand side

2
  • Very nice, would you mind explaining how it works? Thanks – luffe Mar 4 '16 at 18:37
  • @luffe updated! – tachomi Mar 4 '16 at 18:41
5

Perhaps awk

awk -vOFS=', ' '{for (k=1; k<=NF; ++k) $k="\""$k"\""; print}' file
"y10_zcis", "y10_nom", "y10_infl", "y20_zcis", "y20_infl", "y30_zcis", "y30_nom", "y30_infl"
3

You can do:

sed 's/\([^ ]\+\)/"\1",/g; s/,$//' file.txt

Example:

% sed 's/\([^ ]\+\)/"\1",/g; s/,$//' <<<'y10_zcis y10_nom y10_infl y20_zcis y20_infl y30_zcis'   
"y10_zcis", "y10_nom", "y10_infl", "y20_zcis", "y20_infl", "y30_zcis"
2

Using Perl:

perl -lane '$,=", "; foreach(@F) {s/^|$/"/g; push(@f, $_)}; print(@f)' <<<'y10_zcis y10_nom y10_infl y20_zcis y20_infl y30_zcis'
  • $, = ", ": sets the output field separator to ,;
  • foreach(@F) {s/^|$/"/g; push(@f, $_)}: for each space-separated field, wraps the field into double quotes and appends it @f;
  • print(@f): prints the elements of @f separated by the output field separator.
% perl -lane '$,=", "; foreach(@F) {s/^|$/"/g; push(@f, $_)}; print(@f)' <<<'y10_zcis y10_nom y10_infl y20_zcis y20_infl y30_zcis'
"y10_zcis", "y10_nom", "y10_infl", "y20_zcis", "y20_infl", "y30_zcis"
%
2

Assuming you're using bash and your string is already in a variable:

$ a="y10_zcis y10_nom y10_infl y20_zcis y20_infl y30_zcis"
$ 

Then you can do this:

$ echo \"${a// /\", \"}\"
"y10_zcis", "y10_nom", "y10_infl", "y20_zcis", "y20_infl", "y30_zcis"
$ 
1

Yet Another Way, using the shell (for, printf), and a final sed hack:

( for word in $(cat in.txt)
    do printf '"%s", ' $word; done; 
  printf '"\n' ) | 
  sed 's/, "$//'
1
  • 2
    Avoid the for stuff in $(cat file) construct... besides, you're already using sed so use only sed for this job. If you wanted to do it shell only, you could run (with bash4): mapfile -t stuff <infile; printf '"%s"\n' "${stuff[@]// /\", \"}" – don_crissti Mar 4 '16 at 23:12

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.