Summary
How to convert a single string a "b" 'c d' $'e\nf'
into separate arguments, respecting quotes and preserving whitespaces and newlines?
Question
I'm trying to read and process the output of a script that exports value lists, one per line, in form of quoted strings (as created by printf %q
). The values within a list are space-separated, may be quoted, may include spaces and newlines, and are of unknown count.
Example: a "b" 'c d' $'e\nf'
I'm looking for a way to restore the values in a POSIX shell script and handle them as arguments to a shell function.
Desired solutions, in descending priority:
- POSIX shell commands and core utilities like
xargs
,printf
and the like; noeval
- Bash
- A full-blown programming language like perl
Skeleton for the shell script process.sh
:
#!/bin/sh
set -eu
process() {
printf '>%s<\n' "${@}"
}
main() {
value_list="${1}"
# split value list here and set positional parameters
set -- ???
process "${@}"
}
main "${@}"
Desired behaviour
$ process.sh "a \"b\" 'c d' $'e\nf'"
>a<
>b<
>c d<
>e
f<
What happened so far
- I tried different combinations of
printf
(incl.%q
),xargs
,while read
loops, changingIFS
, separation of args with anull
byte, subshell invocations, heredocs. xargs
allows unquoting, but only for spaces, not for newlines, and only without argument-d
.- A
while read
loop can parse args, but does not allow to call a shell function when input is read from a pipe