5

I have hundreds of directories, some nested in other directories, with tens of thousands of files. The files need to have a date/time stamp removed from them.

An example filename is Letter to Client 27May2016~20160531-162719.pdf and I would like for it to go back to being Letter to Client 27May2016.pdf

Another example filename is ABCDEF~20160531-162719 and I would like for it to go back to being ABCDEF. Note that this file has no extension, unlike the example above.

I need a command that I can run at the root of the affected folders that will recursively go through and find/fix the filenames.

( I use Syncthing to sync files, and restored deleted files by copying them from the .stversions directory back to where they were, but found that Syncthing appends that date/time stamp...)

1
  • 1
    What OS are you working on? (That can limit the tools available to you)
    – Jeff Schaller
    Dec 11, 2017 at 18:19

3 Answers 3

6

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.

2
  • The Debian / Ubuntu man pages for it call it prename(1). The man page is pretty bare-bones, though. Dec 12, 2017 at 4:12
  • @PeterCordes, it's rename(1p) in my Debian, and apparently on Ubuntu online manpages too
    – ilkkachu
    Dec 12, 2017 at 7:35
3

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.

-1

Code:

echo "ABCDEF~20160531-162719" | sed "s/~.*//g"
echo "Letter to Client 27May2016~20160531-162719.pdf" |sed "s/~.*[^.pdf]//g"

Above commands achieves the mentioned result

You must log in to answer this question.

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