Change filename from lowercase to uppercase recursively
Assuming that you have the Perl rename provided by Debian and derived distributions such as Debian and Ubuntu, you're almost there. The problem is that -execdir
passes a file name prefixed with ./
to the command. (The reason for that is that some commands treat arguments starting with some characters specially; this way, if you have a file called -foo
, it's passed as ./-foo
and therefore treated as a file and not as an option.) With your regex, this results in $1
being always empty, and hence the new name is identical to the old name.
Accommodate for this ./
in your regular expression.
find . -depth -execdir rename 's/^(\.\/[^.]*)\.(.*)$/\U$1\E.$2/' {} \;
Related videos on Youtube
hd.
Updated on September 18, 2022Comments
-
hd. almost 2 years
I have 1,000,000 files in some folders and subfolders. I want to rename them from lowercase to uppercase using shell commands. I don't want to modify the extension. only filename part.
I have found this one:
rename 's/^([^.]*)\.(.*)$/\U$1\E.$2/' *
but it is not recursive and only works on files in current folder.
Then I tried this one:
find . -depth -execdir rename 's/^([^.]*)\.(.*)$/\U$1\E.$2/' {} \;
But no files changed.
How can I use it recursively?
-
manatwork almost 11 yearsAnd your shell is…? See your shell's manual to find out whether it supports
**
syntax in globbing.bash
(withglobstar
turned on) andzsh
does. -
Admin almost 11 yearsIf possible, you should backup your files before running anything.
-
Gilles 'SO- stop being evil' almost 11 yearsSee also Renaming files to have lower case extensions with 'rename' and Lowercasing all directories under a directory for other methods of changing the case of file names.
-
-
msw almost 11 yearsThis is close to correct but it will fail on filenames with spaces or punctuation in them. It would also be a better answer if you explained why you are using
-type
. -
frostschutz almost 11 yearsnever use
ls
for anything -
manatwork almost 11 yearsAnd how will that traverse the directory structure recursively, as requested in the question?
-
Luis almost 11 years@manatwork: This new script takes into consideration the subdir part of the question that I overlooked before.
-
manatwork almost 11 yearsWondering who upvoted a
ls
call with--reverse
instead of--recursive
? -
manatwork almost 11 yearsOk, it works fine now. But why you use
fn=`echo "${bn%.*}"`
instead offn="${bn%.*}"
? -
Gilles 'SO- stop being evil' almost 11 years@msw What problem do you see with file names with whitespace? This will, however, fail on files in subdirectories that contain lowercase letters, as it will attempt to rename e.g.
foo/bar.ext
toFOO/BAR.ext
(hd. used-execdir
to work around this problem). -
Priya almost 11 yearsThe above command fails on directory name with a dot(.) separator. ex : dir.xyz/abc.txt is being renamed to DIR.xyz/ABC.txt
-
Priya almost 11 years@Gilles , there is no fail with directory as -type f only gives the file path. and renames $1 & $2 only touches the files inside the dir.
-
msw almost 11 yearsIt is ambiguous in the OP whether files or {files and directories} were to be changed. I read
-type f
and Giles infers the opposite. We're both wrong and both right. -
Gilles 'SO- stop being evil' almost 11 years@Ameer
rename
will never be called with an argument of the formdir.xyz/abc.txt
, because-execdir
was used and not-exec
. All the arguments torename
will be of the form./SOMETHING
whereSOMETHING
doesn't contain any slash. Sodir.xyz
will be renamed toDIR.xyz
, which is consistent with the expressed requirements. Thanks to-depth
, this happens afterdir.xyz/abc.txt
has been renamed todir.xyz/ABC.txt
, so there won't be a problem withfind
attempting to move into a directory that's been renamed without it knowing.