So I want to get from a string like:

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

The part "Something, variable".

I could get


using ${q%%,*}.

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

  • 2
    Does it have to be bash? Because this looks a job for a parser.
    – Sobrique
    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
    Dec 22, 2015 at 19:15
  • I prefer bash, but other things are also welcome Dec 22, 2015 at 19:15
  • 2
    Try echo "${q%\"*}"\".
    – jimmij
    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. Dec 23, 2015 at 0:17

4 Answers 4

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.


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


You might handle that like:

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


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).

  • 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. Dec 23, 2015 at 19:35
  • Is it possible to let the multiline script print also the quotes? Dec 23, 2015 at 20:05
  • Yes. Change the 0 to 1.
    – Sobrique
    Dec 23, 2015 at 20:55

You will have to change the Internal Field Separator: IFS

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

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

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

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

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.