Suppose I have a file that contains, among many other things,
\command{arg1,arg2,arg3}
(arguments been paths, expressed with /
, .
, characters and numbers)
But that a user can as well call it with
\command{arg1,
arg2 ,
arg3
}
That is, on several lines and with superfluous spaces.
I'd like to find a regular pattern to include in a shell script so that n variables will contain the n arguments.
How to proceed ?
I managed to write
echo "\command{arg1,
arg2 ,
arg3
}" | sed -n -e 's/\\command//p' | sed 's/,/\n/' | sed 's/{\|}//'
but that only outputs arg1
, and I'm not even sure on how to store it in a variable.
Related:
- matching the text between parenthesis in a multiline text
- finding strings between two characters
- outputing only the part that matches the regular expression
- how to delete everything between a group of brackets
But I was not able to combine all those ingredients to get what I want.
Best Answer
The following creates a shell array
arglist
that contains each of the arguments:By using the
declare
statement, we can see that it worked:Here is another example with the arguments on one line:
Again, it works:
Note that the space in
< <(
is essential. We are redirecting input from a process substitution. Without the space,bash
will try something else entirely.How it works
The
sed
command is a bit subtle. Let's look at it a piece at a time:-n
Don't print lines unless explicitly asked.
/\\command/{...}
If we find a line that contains
\command
, then perform the commands found in the braces which are as follows::a;/}/!{N;b a}
This reads lines into the pattern buffer until we find a line that contains
}
. This way, we get the whole command in at once.s/\\command{//
Remove the
\command{
string.s/[ \n}]//g
Remove all spaces, closing braces, and newlines.
s/,/\n/g
Replace commas with newlines. When this is done, each argument is on a separate line which is what
readarray
wants.p
Print.