If we do not have access to GNU version of xargs/sed , then we need to take the responsibility to quote filenames safe for xargs.
Usage:
./myscript your list of files goes here
#!/bin/bash
# user defined function: qXargs
# backslashes all chars special to xargs:
# SPC/TAB/NL/double quotes, single quotes, and backslash.
qXargs() {
printf '%s\n' "$1" |
sed \
-e "s:[\\'${IFS%?}\"]:\\\\&:g" \
-e '$!s:$:\\:' \
;
}
# loop over command-line arguments
# quote them to make xargs safe and
# break apart arg into head portion and
#'extension and slip in today's date
today=$(date +'%Y-%d-%m')
for arg
do
src=$(qXargs "$arg")
head=$(qXargs "${arg%.*}")
tail=$(qXargs "${arg##*.}")
printf '%s\n%s_%s.%s\n' \
"$src" \
"$head" "$today" "$tail" ;
done | xargs -n 2 -t mv -f --
Assuming GNU versions of utilities.
#!/bin/bash
### this is the ./myscript file
d=$(date +'%Y-%d-%m')
printf '%s\0' "$@" |
sed -Ez "p;s/(.*)(\..*)/\1$d\2/" |
xargs -r0 -n2 -t mv -f --
Notes:
- Your confusion regarding not being able to get the extension from the xargs replacement string {} is bcoz {} is just a placeholder to remind xargs to replace it with the argument. So the shell while parsing the xargs command cannot see it.