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?
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"
""
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.
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\'
bash ignore commas within a quoted string.
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
bash? Because this looks a job for a parser.echo "${q%\"*}"\".