2

I have a shell script that accepts a parameter that is comma delimited,

-s 1234,1244,1567

That is passed to a curl PUT json field. Json needs the values in a "1234","1244","1567" format.

Currently, I am passing the parameter with the quotes already in it: -s "\"1234\",\"1244\",\"1567\"", which works, but the users are complaining that its too much typing and hard to do. So I'd like to just take a comma delimited list like I had at the top and programmatically stick the quotes in.

Basically, I want a parameter to be passed in as 1234,2345 and end up as a variable that is "1234","2345"

I've come to read that easiest approach here is to use sed, but I'm really not familiar with it and all of my efforts are failing.

anubhava
  • 761,203
  • 64
  • 569
  • 643
MABeatty1978
  • 115
  • 1
  • 3
  • 14

5 Answers5

5

You can do this in BASH:

$> arg='1234,1244,1567'

$> echo "\"${arg//,/\",\"}\""
"1234","1244","1567"
anubhava
  • 761,203
  • 64
  • 569
  • 643
3

awk to the rescue!

$ awk -F, -v OFS='","' -v q='"' '{$1=$1; print q $0 q}' <<< "1234,1244,1567"

"1234","1244","1567"

or shorter with sed

$ sed -r 's/[^,]+/"&"/g' <<< "1234,1244,1567"

"1234","1244","1567"

translating this back to awk

$ awk '{print gensub(/([^,]+)/,"\"\\1\"","g")}' <<< "1234,1244,1567"

"1234","1244","1567"
karakfa
  • 66,216
  • 7
  • 41
  • 56
1

you can use this:

echo QV=$(echo 1234,2345,56788 | sed -e 's/^/"/' -e 's/$/"/' -e 's/,/","/g')

result:

echo $QV
"1234","2345","56788"

just add double quotes at start, end, and replace commas with quote/comma/quote globally.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
1

easy to do with sed

$ echo '1234,1244,1567' | sed 's/[0-9]*/"\0"/g'
"1234","1244","1567"
  • [0-9]* zero more consecutive digits, since * is greedy it will try to match as many as possible
  • "\0" double quote the matched pattern, entire match is by default saved in \0
  • g global flag, to replace all such patterns

In case, \0 isn't recognized in some sed versions, use & instead:

$ echo '1234,1244,1567' | sed 's/[0-9]*/"&"/g'
"1234","1244","1567"


Similar solution with perl

$ echo '1234,1244,1567' | perl -pe 's/\d+/"$&"/g'
"1234","1244","1567"


Note: Using * instead of + with perl will give

$ echo '1234,1244,1567' | perl -pe 's/\d*/"$&"/g'
"1234""","1244""","1567"""
""$ 

I think this difference between sed and perl is similar to this question: GNU sed, ^ and $ with | when first/last character matches

Community
  • 1
  • 1
Sundeep
  • 23,246
  • 2
  • 28
  • 103
  • The `\0` isn't working for me, and results in each value being `0`. Are you sure you don't mean `&`? – ghoti Oct 06 '16 at 02:00
  • 1
    I tried in a recent OS X, FreeBSD 10.3, and a Busybox installation whose `sed --version` reports `This is not GNU sed 4.0`. Also tested on GNU sed 4.2.1 where it worked. Looks to me as if `\0` might be specific to GNU, I think I'd go with `sed -r 's/[0-9]+/"&"/g'`. – ghoti Oct 06 '16 at 08:16
  • 1
    Thanks for the update! Great that you're keeping portability in mind. I found that busybox's sed supported `-r` but not `-E`, which is why I suggested that. Since FreeBSD added `-r` for compatibility, I no longer have any systems that do not support `-r`. – ghoti Oct 06 '16 at 09:01
0

Using sed:

$ echo 1234,1244,1567 | sed 's/\([0-9]\+\)/\"\1\"/g'
"1234","1244","1567"

ie. replace all strings of numbers with the same strings of numbers quoted using backreferencing (\1).

James Brown
  • 36,089
  • 7
  • 43
  • 59