I already wrote a summary in the German Synology board:
#Step 1: Listing all affected directories and files
#Step 2: Changing the stuff
I wrote the walkthrough in English.
---
So ... here we go. First I have to say that you should not just start typing the command lines and hope that it will fix your stuff. You might change some parts of the commands to get your desired results.
As far as you understand what the commands are doing exactly, you will have the control. Otherwise something might happen, which you did not want to happen...
Step by Step:
1. Access the Diskstation via SSH. You have to enable the SSH service in the DS settings first, check this for help.
Code: Select all
ssh admin@diskstation.local -p 22The -p option specified the port. This has been set in the DS system preferences earlier.
An admin account is sufficient. Don't use the root, so you make sure that no DSM system own folders and files will be affected by changes.
2. List the files and directories! I have run several individual commands, so I have a specific list for each case and do not have to look through a long list. Directories and files that are located in a path which contains "@eaDir" or "#recycle" will not be observed. Thus, all directories and files in the share bins are irrelevant for us. The search goes through all volumes, so it starts with /volume1 and runs till no volume is left. The command will save the list in a CSV file in the home share of the user which is currently logged in via SSH. In this case it is admin. Here you might have to adjust the path of you want to save the CSV files in another directory or if your share "homes" is not located on /volume1.
Not the command lines:
1. Find directories with a period/dot at the end:
Code: Select all
find /volume* -name "*." -type d -not -path "*@eaDir*" -not -path "*#recycle*" -printf '"%h","%f","%CY-%Cm-%Cd %CT","%s","%u","%M"\n' > /volume1/homes/$USER/dir_dot_end.csv2. Find all directories with a space at the end:
Code: Select all
find /volume* -name "* " -type d -not -path "*@eaDir*" -not -path "*#recycle*" -printf '"%h","%f","%CY-%Cm-%Cd %CT","%s","%u","%M"\n' > /volume1/homes/$USER/dir_space_end.csv3. List all directories which contain the following chars in their names:
: ; ? " \ / < > * |
Code: Select all
find /volume* -name "*[\\:\;\"\\\?\<\>\*\|]*" -type d -not -path "*@eaDir*" -not -path "*#recycle*" -printf '"%h","%f","%CY-%Cm-%Cd %CT","%s","%u","%M"\n' > /volume1/homes/$USER/dir_not_allowed_chars.csv4. List all files which contain the chars above:
Code: Select all
find /volume* -name "*[\\:\;\"\\\?\<\>\*\|]*" -type f -not -path "*@eaDir*" -not -path "*#recycle*" -printf '"%h","%f","%CY-%Cm-%Cd %CT","%s","%u","%M"\n' > /volume1/homes/$USER/files_not_allowed_chars.csv5. This should have been created 4 .csv files. If there are some inch chars ( " ) inside the path or the targeted file/dir name, then excel and other table handling applications wont interpret the CSV correctly. Thus, you will have to find and replace these single chars with two inch signs: ( " " ). This page will help you somehow finding the bad lines. Additional information of the correct CSV structure is available here.
Example of Incorrect CSV line and the correction:
Code: Select all
"/volume1/homes/username/Test","Data for 27" Screen","2016-09-27 10:00:59.0612228610","4096","username","drwxrwxrwx"
↑
change to:
↓
"/volume1/homes/username/Test","Data for 27"" Screen","2016-09-27 10:00:59.0612228610","4096","username","drwxrwxrwx"
------
Now you should have got an overview of the amount of affected data, so you can either rename the files and directories manually or proceed as follows.
I use the same commands again to create another list, but this time it will output a .sh bash script which needs to be run afterwards.
1. Directories containing a blank or dot at the end will get an underscore, plus a random Number to prevent overwriting (_5688).
a) create .sh file:
Code: Select all
# Here, the folders are listed with spaces and written in the .sh
find /volume* -name "* " -type d -not -path "*@eaDir*" -not -path "*#recycle*" -printf 'find "%h" -type d -name "* " -print0 | while IFS= read -r -d "" folder ; do mv -- "$folder" "${folder}_$RANDOM"; done\n' > /volume1/homes/$USER/dir_change_end.sh
# Now the folders are listed with spaces and written at the end of the .sh
find /volume* -name "*." -type d -not -path "*@eaDir*" -not -path "*#recycle*" -printf 'find "%h" -type d -name "*." -print0 | while IFS= read -r -d "" folder ; do mv -- "$folder" "${folder}_$RANDOM"; done\n' >> /volume1/homes/$USER/dir_change_end.shb) run the .sh file:
Code: Select all
/volume1/homes/$USER/dir_change_end.shThis should have fixed all folders with the dot or space at the end. To make sure that it worked you can run again one of the first CSV listing commands and repeat the changes once again.
In case of parent folders being affected by the renaming, you will have to run it again because its subfolders cant be addressed by the script anymore, their name changed. Heres an example:
Code: Select all
/volume1/homes/username/Test / >> changed to >> /volume1/homes/username/Test _51247/
Will no longer be found because the parent folder has changed:
/volume1/homes/username/Test /Subfolder /---
Now lets proceed with the renaming of directories and files which contain bad characters.
Its basically the same way, I have got two processes:
1. Directories containing : ; \ ? < > * |. Every single char will be replaced with an underscore.
I have excluded the share for Time Machine Backups, since I did not know if the backup (backupname.sparsebundle) is interpreted as a directory.
Thus, the backup should not be touched. Here you may definitely need to change the name of the share. For me it's just "Time Machine Backups".
Also the bin of the shares and all folders including "@" are excluded, thus remain System folders (like @tmp) untouched.
Code: Select all
find /volume* -name "*[\:\;\"\\\?\<\>\*\|]*" -type d -not -path "*@*" -not -path "*#recycle*" -not -path "*Time Machine Backups*" -printf 'find "%h" _X_X_X_\n' > /volume1/homes/$USER/folders_not_allowed_chars.shThis created a .sh file in the home share of the logged-in user, as usual. Then the string _X_X_X_ must be replaced with the following text. I have to use the find & replace function of a simple text editor. (Because I have not got it done by a bash command. The escaping of each character was too stressful, is not my skill).
Code: Select all
_X_X_X_
change to:
-type d -name '*[\:\;\"\\\?\<\>\*\|]*' -not -path "*@*" -not -path "*#recycle*" -not -path "*Time Machine Backups*" -print0 | while IFS= read -r -d '' file ; do ext="${file##*.}" ; filename="${file%.*}" ; file_clean="$(echo $filename | tr "\:\;\"\\\?\<\>\*\|" "_")" ; final="$file_clean.$ext" ; mv -n -v "$file" "$final" ; doneAfter that, the folders_not_allowed_chars.sh will be run:
Code: Select all
/volume1/homes/$USER/folders_not_allowed_chars.shYou will possibly have to rerun the script.
2. Files containing : ; \ ? < > * |. These chars will be replaced with an underscore.
Code: Select all
find /volume* -name "*[\:\;\"\\\?\<\>\*\|]*" -type f -not -path "*@*" -not -path "*#recycle*" -not -path "*Time Machine Backups*" -printf 'find "%h" _X_X_X_\n' > /volume1/homes/$USER/files_not_allowed_chars.shCode: Select all
_X_X_X_
change to:
-type f -name '*[\:\;\"\\\?\<\>\*\|]*' -not -path "*@*" -not -path "*#recycle*" -not -path "*Time Machine Backups*" -print0 | while IFS= read -r -d '' file ; do ext="${file##*.}" ; filename="${file%.*}" ; file_clean="$(echo $filename | tr "\:\;\"\\\?\<\>\*\|" "_")" ; final="$file_clean.$ext" ; mv -n -v "$file" "$final" ; doneRun the files_not_allowed_chars.sh afterwards:
Code: Select all
/volume1/homes/$USER/files_not_allowed_chars.shAgain: you might have to repeat that script.
---
Of course you can customize the search pattern, so the script will change other characters or strings in your file and directory names. Just be careful with that thing and test the stuff in a test environment before you run it over all your data.
So that's it, folder and file names have been renamed correctly – hopefully
And for those who recognize lower transfer rates, like me:
If you are in a safe network, if you are sure that no one will use your mac, you can disable the signing on your mac. Read this article.
My AFP transfer rate was high with ~100MB/s, after switching to SMB it was only ~50MB/s.
After disabling signing I went back to ~100MB/s, its even faster than AFP.
Best wishes!



