Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Just a slight modification to rename all files recursively, but it worth nothing: there may be uppercase characters in the directory names, too, which should also be changed, so the problem needs a different approach.
As for Windows: it is really great in listing files (that is why so many people use it).
But what about renaming those files? Your mouse will burn away.
Here is the same script being slightly modified to be recursive:
#!/bin/bash
dir=/whatever/directory
for file in `find $dir` ; do
# ANYCASE TO UPPERCASE:
newshortname=`echo $file | sed "s/$dir//" | tr '[a-z]' '[A-Z]'`
mv $file $dir/$newshortname
done
Please note that the script in its present form has serious restrictions: it only works correctly if there are no uppercase letters in any directory names, and there are no spaces in either the directory or filenames. Otherwise it will fail or give unexpected result.
So, use it with special caution.
As I told you I found it difficult to overcome the restrictions with a simple script - though I am not a script guru. However it is easy to test whether the directory and filenames comply with the restrictions.
For this reason, you might insert these lines into the beginning of the script right after the 'dir=/whatever/directory' line:
# Test for uppercase in directory names
if [ `find $dir -type d | grep -c -E "([[:upper:]])"` -gt 0 ] ; then
echo "Directory names contain uppercase:"
find $dir -type d | grep -E "([[:upper:]])"
exit
fi
if [ `find $dir | grep -c -E "([ ])"` -gt 0 ] ; then
echo "Directory or file names contain spaces:"
find $dir | grep -E "([ ])"
exit
fi
Now, I am really curious how would you do that with the great command prompt of windows?
Please let me know!
Well, in Windows it's relatively unnecessary because it's case-insensitive on filenames. Anyway, this script requires you to have sed installed, but that's a simple matter.
dir /s /b /l > files.txt
sed "s/(*.?)\n/ren \1 \1\n/" < files.txt > fix.bat
call fix.bat
del fix.bat
del files.txt
Actually I haven't tested this script, but the only thing I'm not sure about is the regular expression syntax for sed.
Edit: And actually, none of those shell scripts listed above work either... just gives me file-already-exists errors.
Sorry...This happens when you do not test the script you write...
It was because of sed: since full filenames contain '/', sed cannot use / as delimiter for the s command (now it uses '!' as the delimiter).
I corrected the bug, and also made little additions to avoid unnecessary attempts to rename files that do not contain uppercase, and $dir itself.
This time I tested the script, and it worked fine. Here it is:
dir=/some/directory
# Test for uppercase in directory names
if [ `find $dir -type d | grep -c -E "([[:upper:]])"` -gt 0 ] ; then
echo "Directory names contain uppercase:"
find $dir -type d | grep -E "([[:upper:]])"
exit
fi
# Test for spaces or sed delimiter in directory or filenames
if [ `find $dir | grep -c -E "([ !])"` -gt 0 ] ; then
echo "Directory or file names contain spaces or delimiter used for sed:"
find $dir | grep -E "([ !])"
exit
fi
for file in `find $dir` ; do
# ANYCASE TO UPPERCASE:
newshortname=`echo $file | sed "s!$dir/!!" | tr '[A-Z]' '[a-z]'`
if [ $file != $dir/$newshortname ] && [ $file != $dir ] ; then
mv $file $dir/$newshortname
fi
done
I think that the windows sample script would only work on windows, because it seems to rely much on the case insensitivity of winDOS.
The problem is: on unix, the order of renaming the files and (sub)directories is not arbitrary.
Since you create the recursive directory listing at the beginning of the script, it might happen that you first rename a directory (since it had an uppercase), only then you try to rename a file in it. Naturally this would not succeed, since the file is in other directory by that time.
However, I found out how could a simple unix script do this.
In two turns:
First: find only the files (find $dir -type f) and rename them.
Second: find only the directories (find $dir -type d), order (sort) them according to their level in the directory hierarchy (sub-directories first!) (maybe grep or awk could count '/' characters in the full directory names and order the directories based on this count), then rename the directories in this order.
Since I am not a script guru, however, it would take me several hours of reading and experimentation to write this script.
So, either you will be lucky to get help from someone who is more skillful than me or you do the trick on your own.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.