Make sure you use one of the perl
-based rename
variants, sometimes called prename
, not the one from util-linux
(sometimes called rename.ul
).
The one from util-linux
is much more limited (despite being much newer), uses a different syntax, can only replace fixed strings and can't replace all the occurrences of a string.
Here, I'd use perl rename
variants, make sure to only convert newlines in the file names, not the directory components leading to them, and use -depth
to process leaves before branches.
perl
recognises \n
as meaning a newline, so you don't need to use $'...'
for its code argument (though it's fine if you do contrary to what I initially thought).
find . -depth -name $'*\n*' -exec rename '
s{[^/]*\z}{$& =~ y/\n/ /r}e' '{}' +
Or use -execdir
if available (though that will run at least one rename
per directory with files with \n
within):
find . -depth -name $'*\n*' -execdir rename 'y/\n/ /' {} +
Or you could use zsh
's zmv
:
autoload zmv
NL=$'\n'
zmv "(**/)(*$NL*)(#qD)" '$1${2//$NL/ }'
(which contrary to the find
-based approaches will still work even if file names contain sequences of bytes that don't form valid characters. It will also bail out without doing anything if it detects a conflict).
\n
you want to remove? Apparently, in the question you linked to, the relevant characted was "carriage return"\r
instead. Maybe that's what you need too? – NickD Sep 18 '19 at 12:11rename
on your system is theutil-linux
implementation (whereas the linked answer assumes one of the Perl-based implementations). What type or flavor of Unix / Linux are you using? – steeldriver Sep 18 '19 at 13:17$ rename --version
I get
– Georgios Mavropalias Sep 18 '19 at 13:33rename from util-linux 2.34