I was trying to use bash's string replace function in xargs. But I keep getting bad substitution errors. The command I tried to use:
ls / | xargs -I{} sh -c 'x={};echo ${x/something/somethingelse}'
I could do it with sed, but I cannot figure out what's the problem with the above command.
Error message: sh: 1: Bad substitution
As KamilCuk has stated below, this was mostly due to using dash as /bin/sh.
CodePudding user response:
Issues:
${var/a/b}
expansion is a Bash feature, which may be not available on other shells (most notablydash
).Do not parse ls. https://unix.stackexchange.com/questions/128985/why-not-parse-ls-and-what-to-do-instead
'x={};
the{}
part is getting interpreted by the shell, according to shell gramma rules.xargs
by default interprets"
'
\
in input strings.
Remedies:
- Call Bash explicitly if you intent to use Bash features.
- Do not use
ls
. (Or ignore best practice) - Do no use
{}
inside-c
scripts. Use arguments. Remember to quote argument expansions. - Explicitly specify delimiter for
xargs
.
For example:
printf "%s\n" /* | xargs -d '\n' -n1 bash -c 'x="$1"; echo ${x/something/somethingelse}' --
printf "%s\n" /* | xargs -d '\n' -I{} bash -c 'x="$1"; echo ${x/something/somethingelse}' -- {}
find / -maxdepth 1 -mindepth 1 | xargs -d '\n' -n1 bash -c 'x="$1"; echo ${x/something/somethingelse}' --
find / -mindepth 1 -mindepth 1 -print0 | xargs -0 -n1 bash -c 'x="$1"; echo ${x/something/somethingelse}' --