This is homework!

I'm trying to replace all spaces in file names with an underscore in the yay directory. It asks me to use the commands xargs and sh without using $(command). I tried using conducts of commands, but it keeps displaying this message:

sh: 1: Bad substitution

Could someone explain why this message keeps popping up?

Here's are the commands I tired using:

find yay -type f -print0 | xargs -0 -I {} sh -c 'newname="${1// /_}"; mv "$1" "$newname"' sh


find yay -type f -exec sh -c 'mv "$1" "${1// /_}"' _ {} \;
  • 1
    sh is only required to be POSIX compliant, and ${parameter//pattern/replacement} isn't one of the POSIX parameter expansion capabilities - it is supported in shells such as ksh, bash, and zsh Oct 18, 2023 at 15:17

1 Answer 1


The sh shell does not understand the / substitution. (It does understand % and and #, though.) You need a shell such as bash for this:

find yay -type f -exec bash -c 'mv -- "$1" "${1// /_}"' _ {} \;

You can more efficiently write this by reducing the number of invocations of the shell (currently one per file), and only renaming a file if the destination does not already exist:

find yay -type f -name '* *' -exec bash -c 'for f in "$@"; do g=${f// /_}; [ ! -e "$g" ] && mv -f -- "$f" "$g"; done' _ {} +

While testing, prefix mv with echo and you'll get a printout of (an approximation to) what would be executed without any action really being taken.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .