Let’s talk about how wildcards work for a minute.
cp *.txt foo
doesn’t actually invoke cp
with an argument *.txt
, if any files matching that glob exist. Instead, it runs something like this:
cp a.txt b.txt c.txt foo
Similarly, something like
mv *.txt *.old
…can’t possibly know what to do, because when it’s invoked, what it sees is:
mv a.txt b.txt c.txt *.old
or, worse, if you already have a file named z.old
, it’ll see:
mv a.txt b.txt c.txt z.old
Thus, you need to use different tools. Consider:
# REPLACES: mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
for f in /data/*/Sample_*/logs/*_Data_time.err; do
mv "$f" "${f%_Data_time.err}_Data_time_orig.err"
done
# REPLACES: cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*.sh; do
cp "$f" "${f%.sh}_orig.sh"
done
# REPLACES: sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*_orig.sh; do
if [[ -e "$f" ]]; then
# honor the script's shebang and let it choose an interpreter to use
"$f"
else
# script is not executable, assume POSIX sh (not bash, ksh, etc)
sh "$f"
fi
done
This uses a parameter expansion to strip off the tail end of the old name before adding the new name.