1

So I want to get from a string like:

q='"Something, variable", another part, third one'

The part "Something, variable".

I could get

'"Something'

using ${q%%,*}.

But how could I let bash ignore commas (or other characters) within quotes?

9
  • 2
    Does it have to be bash? Because this looks a job for a parser.
    – Sobrique
    Commented Dec 22, 2015 at 19:14
  • @Sobrique Agreed. Doing this in bash isn't going to be fun. In python this is already implemented (or php, perl, ruby, etc.)
    – David King
    Commented Dec 22, 2015 at 19:15
  • I prefer bash, but other things are also welcome Commented Dec 22, 2015 at 19:15
  • 2
    Try echo "${q%\"*}"\".
    – jimmij
    Commented Dec 22, 2015 at 19:21
  • 1
    @mikeserv hard to tell: “Somehow it seems to fill my head with ideas — only I don't exactly know what they are!”. It needs its grammar improving. Commented Dec 23, 2015 at 0:17

4 Answers 4

1
echo "${q%"${q#*\"*\"}"}"

"Something, variable"

...works for just those two quotes by using the result of removing up to the second " double-quote found in $q as the literally-interpreted (read - inner-quoted) pattern string to strip from $q's tail. If two double-quotes cannot be found in $q the expansion is null.

Also, if there were any characters leading the first of these in $q they would also be retained as well, though.

so...

q='x""'
echo "${q%"${q#*\"*\"}"}"

x""

You might handle that like:

[ -z "${q##\"*}" ] || q=\"${q#*\"}
echo "$q"

""
0

This is pretty simple using perl is it has the Text::ParseWords parser in core:

#!/usr/bin/env perl
use strict;
use warnings;
use Text::ParseWords; 
use Data::Dumper; 

my $q = '"Something, variable", another part, third one';
my @words = parse_line ( ',', 0, $q );

#dump words:
print Dumper \@words; 

#just output first one: 
print $words[0];

Or to one-liner-ify it so you can use it inline in shell:

echo $q | perl -MText::ParseWords -e '@w=parse_line(',',0,<>);print $w[0]'

Which will read it from STDIN and print the parsed first 'word' in STDOUT.

(Or you could feed it in via $ENV{q} or similar).

3
  • echo $q | perl -MText::ParseWords -e '@w=parse_line(",",1,<>);print $w[0]' works for me. By changing the w[0] in 1 I can get 'another part' I need. Commented Dec 23, 2015 at 19:35
  • Is it possible to let the multiline script print also the quotes? Commented Dec 23, 2015 at 20:05
  • Yes. Change the 0 to 1.
    – Sobrique
    Commented Dec 23, 2015 at 20:55
0

You will have to change the Internal Field Separator: IFS

q='"Something, variable", another part, third one'

# save actual IFS
_old_ifs="${IFS}"
# set IFS to ","
IFS=","
# split q with this new IFS
set -- `echo ${q}`
# restore standard IFS
IFS="${_old_ifs}"

echo \'$1\'
3
  • what does it do? Commented Dec 23, 2015 at 19:40
  • What you asked for: make bash ignore commas within a quoted string.
    – dan
    Commented Dec 23, 2015 at 23:00
  • @danielAzuelos Within quotes, and across all "$q". Commented Dec 24, 2015 at 14:34
0

You can pipe it through cut, specifying the double-quote character as a field delimiter and asking the just the second field be output.

$ q='"Something, variable", another part, third one'

$ echo $q | cut -d\" -f2
Something, variable

You must log in to answer this question.

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