I've found a bad habit file naming among the users of the QNAP Linux NAS system I'm administering. We have a Mac OS network, and some folders and files are named using the "/" character that I know it's causing problems to Linux file system. As a matter of fact, from the Mac OS side, the files containing "/" simply disappear, since QTS replaces automatically all instances with "/" with ":".
I'd like to search and rename filenames from ":" to "_".
Discussing on the web I've found that I can SSH connect to the Linux NAS from my Mac with Terminal and perform a script like this:
for f in $(find /share/Public/demofind -name "*:*"); do mv $f ${f/:/_}; done
assuming that the files are in /demofind folder.
I launched the script, but got this error:
[/share/Public] # for f in $(find /share/Public/demofind/ -name "*:*"); do mv $f ${f/:/_}; done
mv: unable to rename `/share/Public/demofind/Redazionali': No such file or directory
mv: unable to rename `01:03:19.pdf': No such file or directory
mv: unable to rename `/share/Public/demofind/Redazionali': No such file or directory
mv: unable to rename `06:09:19.pdf': No such file or directory
[/share/Public] # for f in $(find /share/Public/demofind/ -name "*:*"); do mv $f ${f/:/_}; done
mv: unable to rename `/share/Public/demofind/Redazionali': No such file or directory
mv: unable to rename `01:03:19.pdf': No such file or directory
mv: unable to rename `/share/Public/demofind/Redazionali': No such file or directory
mv: unable to rename `06:09:19.pdf': No such file or directory
By the way, the files to rename have a syntax like this: "Redazionali 06:09:19.pdf"
Any help ? Thanks !
CodePudding user response:
The immediate problem is that you have broken quoting but your code has other problems too.
The robust solution would be
find /share/Public/demofind -name "*:*" -exec bash -c '
for f; do mv "$f"; "${f//:/_}"; done' _ {}
Putting the for loop inside find -exec works around pesky problems around file names with unusual characters in them, not just spaces (though your for loop would also inherently break on just single spaces, too; you would have to separately tell the shell to not perform whitespace tokenization if you used the output from find in a command substitution, but again, the proper fix is to simply not do that).
For details, please review https://mywiki.wooledge.org/BashFAQ/020
CodePudding user response:
Thanks for the input tripleee.
I tried out your suggestion, but as soon as I enter find /share/Public/demofind -name "*:*" -exec bash -c 'for f; do mv "$f"; "${f//:/_}"; done' _ {}
I get this output:
BusyBox v1.01 (2021.12.12-04:24 0000) multi-call binary Usage: find [PATH...] [EXPRESSION] Search for files in a directory hierarchy. The default PATH is the current directory; default EXPRESSION is '-print'
CodePudding user response:
Tripleee,
I tried out also for f in "$(find /share/Public/demofind -name "*:*")"; do mv "$f" "${f/:/_}"; done
and in this case I got:
mv: unable to rename `': No such file or directory
I think I've got a syntax error somewhere... sorry but I'm just starting to learn how to script with Bash.
