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 Dec 22 '15 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 '15 at 19:15
  • I prefer bash, but other things are also welcome – kees broeksma Dec 22 '15 at 19:15
  • 2
    Try echo "${q%\"*}"\". – jimmij Dec 22 '15 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. – ctrl-alt-delor Dec 23 '15 at 0:17
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. – kees broeksma Dec 23 '15 at 19:35
  • Is it possible to let the multiline script print also the quotes? – kees broeksma Dec 23 '15 at 20:05
  • Yes. Change the 0 to 1. – Sobrique Dec 23 '15 at 20:55
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

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? – kees broeksma Dec 23 '15 at 19:40
  • What you asked for: make bash ignore commas within a quoted string. – dan Dec 23 '15 at 23:00
  • @danielAzuelos Within quotes, and across all "$q". – Rany Albeg Wein Dec 24 '15 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

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.