Home > front end >  rename files with filename lengths longer than 143 characters on synology nas
rename files with filename lengths longer than 143 characters on synology nas

Time:10-05

i am trying to encrypt a folder on our Synology Nas but have found roughly 250 files with filenames longer than 143 characters. Is there any command i can use to remove all characters from the end of the file names so it is under 143 characters in length.

The command i used to find the files

find . -type f -name '???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????*'

I was hoping to be able to navigate to the 8-9 or so directories that hold these chunks of files and be able to run a line of code that found the files with names longer than n characters and drop the extra characters to get it under 143.

thank you!

CodePudding user response:

I'm not familiar with Synology, but if you have a rename command which accepts Perl regex substitutions, and you are fine with assuming that no two files in the same directory have the same 143-character prefix (or losing one of them in this case is acceptable), I guess something like

find . -type f -regex '.*/[^/]\{143\}[^/] ' -exec rename 's%([^/]{143})[^/] $%$1%' {}  

If you don't have this version of the nonstandard rename command, the simplest solution might be to pipe find's output to Perl and then pipe that to sh:

find . -type f -regex '.*/[^/]\{143\}[^/] ' |
perl -pe 's%(.*/)([^/]{143})([^/] )$%mv "$1$2$3" "$1$2"' |
sh

If you don't have access to Perl, the same script could be refactored into a sed command, though the regex will be slightly different because they speak different dialects.

find . -type f -regex '.*/[^/]\{143\}[^/] ' |
sed 's%\(.*/\)\([^/]\{143\}\)\([^/]\ \)$%mv "\1\2\3" "\1\2"' |
sh

This has some naïve assumptions about your file names - if they could contain newlines or double quotes, you need something sturdier (see https://mywiki.wooledge.org/BashFAQ/020). In rough terms, maybe try

find . -type f -regex '.*/[^/]\{143\}[^/] ' -exec bash -c 'for f; do
    g=${f##*/}
    mv -- "$f" "${f%/*}/${g:0:143}"
  done' _ {}  
  • Related