Remove characters from file names recursively
Meet the Perl rename
tool:
$ rename -n -v 's/~[^.]+//' *~*
rename(ABCDEF~20160531-162719, ABCDEF)
rename(Letter to Client 27May2016~20160531-162719.pdf, Letter to Client 27May2016.pdf)
(online man page, also see this Q)
That regex says to match a tilde, as many characters that are not dots, but at least one; and to replace whatever matched with an empty string. Remove the -n
to actually do the replace. We could change the pattern to ~[-0-9]+
to just replace digits and dashes.
Sorry, you said "recursively", so lets use find
:
$ find -type f -name "*~*" -execdir rename -n -v 's/~[-0-9]+//' {} +
rename(./ABCDEF~20160531-162719, ./ABCDEF)
rename(./Letter to Client 27May2016~20160531-162719.pdf, ./Letter to Client 27May2016.pdf)
Or just with Bash or ksh, though directories with ~
followed by digits will break this:
$ shopt -s extglob # not needed in ksh (as far as I can tell)
$ shopt -s globstar # 'set -o globstar' in ksh
$ for f in **/*~* ; do
g=${f//~+([-0-9])/};
echo mv -- "$f" "$g"
done
mv -- ABCDEF~20160531-162719 ABCDEF
mv -- Letter to Client 27May2016~20160531-162719.pdf Letter to Client 27May2016.pdf
Again, remove the echo
to actually do the rename.
In bash:
shopt -s globstar
for file in **/*~[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]*
do
echo mv -- "$file" "${file/~[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]/}"
done
This finds all filenames (recursively) that match the date pattern (following a tilde), then echoes a sample mv
command to rename them. The target of the mv command is the result of a bash parameter expansion that replaces any tilde-datestring text with nothing.