Restore original name versioned files with linux command

Hello there!

Yesterday I tried to set up Syncthing to synchronise files between four devices, but I fucked up. I accidentally deleted a folder and the change was done on all my devices. Luckily I had file versioning enabled on one device, so I didn’t lose my files. So I copied these versioned files to their original destination. The downside was that all the files had been renamed with ~date-time in the middle of it, some files were pretty important (it is my windows Documents folder, with a lot of config files) so I had to find a way to restore their original name.

It’s taken a lot of testing, fucking around and reading obscure forums, but I finally found a one-liner that fulfills my needst:

find . -type f  | sed -e 'p;s/\(.*\)~20[0-9]\{6\}-[0-9]\{6\}\(.*\)/\1\2/' | xargs -n2 -d'\n' mv

Just run it in the top directory where you want to rename all the files (files in the subdirectories are renamed too). Normal files aren’t affected by this.

I’m not asking for help, I posted to save other people in the same situation time and effort.

Have a nice day!

4 Likes

Thanks! (I tagged your post with “Howto”)

Does that work for special characters? Spaces, and so on?

It works with spaces :slight_smile: But it cannot handle newlines in folder names…

I wrote the following script

#! /bin/bash

working_path="/full/path/to/syncthing/directory"
backup_path="$working_path/.stversions/"

pushd "$backup_path"

find . -type f | while read file; do
    sub_path=$(dirname "$file") # get relative subdirectories
    sub_path=${sub_path#\./} # remove ./ at front of string
    target_path=${working_path}/${sub_path}  
    if [ -d "$target_path" ]; then # check if target path exists
        basename=$(basename "$file")
        ending=${basename##*\.} # get ending
        name=${basename%%\~*} # get filename
        cp -v "$file" "$working_path/$sub_path/$name.$ending" # copy file
    else
        echo "No valid directory: $working_path/$sub_path" 
    fi
done

popd

It works only if all directories still exist. Use it at your own risk.

The Linux command line to remove version stamps may also work on Windows under the new bash interpreter included with Windows 10. When I get a chance to confirm, I’ll report back.

thanks!