ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
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.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hello.Please help, how to rename recursive dirs, sub dirs and files in them.
This is the results of my experiments :
Code:
zarine@zomane:~/1a-script/recrensp$ find ./ -iname "*.bla" -exec rename -v -n 'y/A-Z/a-z/' "{}" \;
./DFg RgF/ffff dDd.bla renamed as ./dfg rgf/ffff ddd.bla
./DFg RgF/dDFd dfdf.bla renamed as ./dfg rgf/ddfd dfdf.bla
./rrr fff/ewrWE pppp.bla renamed as ./rrr fff/ewrwe pppp.bla
./rrr fff/WdgfAAArwe ppRGR.bla renamed as ./rrr fff/wdgfaaarwe pprgr.bla
./rrr fff/Wdg.QQrwe pppp.bla renamed as ./rrr fff/wdg.qqrwe pppp.bla
./rrr fff/sfsd.QQ.r rr.bla renamed as ./rrr fff/sfsd.qq.r rr.bla
./rrr fff/fsfs.HHHH sfsdf.bla renamed as ./rrr fff/fsfs.hhhh sfsdf.bla
./rrr fff/iiuySDy wwww.bla renamed as ./rrr fff/iiuysdy wwww.bla
./aaa fgdfg/eeeEEe qqqq.bla renamed as ./aaa fgdfg/eeeeee qqqq.bla
./aaa fgdfg/GGgg sss.bla renamed as ./aaa fgdfg/gggg sss.bla
./aaa fgdfg/ZXC SSS.bla renamed as ./aaa fgdfg/zxc sss.bla
zarine@zomane:~/1a-script/recrensp$ find ./ -iname "*.bla" -exec rename -v 'y/A-Z/a-z/' "{}" \;
Can't rename ./DFg RgF/ffff dDd.bla ./dfg rgf/ffff ddd.bla: No such file or directory
Can't rename ./DFg RgF/dDFd dfdf.bla ./dfg rgf/ddfd dfdf.bla: No such file or directory
./rrr fff/ewrWE pppp.bla renamed as ./rrr fff/ewrwe pppp.bla
./rrr fff/WdgfAAArwe ppRGR.bla renamed as ./rrr fff/wdgfaaarwe pprgr.bla
./rrr fff/Wdg.QQrwe pppp.bla renamed as ./rrr fff/wdg.qqrwe pppp.bla
./rrr fff/sfsd.QQ.r rr.bla renamed as ./rrr fff/sfsd.qq.r rr.bla
./rrr fff/fsfs.HHHH sfsdf.bla renamed as ./rrr fff/fsfs.hhhh sfsdf.bla
./rrr fff/iiuySDy wwww.bla renamed as ./rrr fff/iiuysdy wwww.bla
./aaa fgdfg/eeeEEe qqqq.bla renamed as ./aaa fgdfg/eeeeee qqqq.bla
./aaa fgdfg/GGgg sss.bla renamed as ./aaa fgdfg/gggg sss.bla
./aaa fgdfg/ZXC SSS.bla renamed as ./aaa fgdfg/zxc sss.bla
zarine@zomane:~/1a-script/recrensp$ find ./ -iname "*.bla" -exec rename -v 'y/a-z/A-Z/' "{}" \;
Can't rename ./DFg RgF/ffff dDd.bla ./DFG RGF/FFFF DDD.BLA: No such file or directory
Can't rename ./DFg RgF/dDFd dfdf.bla ./DFG RGF/DDFD DFDF.BLA: No such file or directory
Can't rename ./rrr fff/fsfs.hhhh sfsdf.bla ./RRR FFF/FSFS.HHHH SFSDF.BLA: No such file or directory
Can't rename ./rrr fff/sfsd.qq.r rr.bla ./RRR FFF/SFSD.QQ.R RR.BLA: No such file or directory
Can't rename ./rrr fff/ewrwe pppp.bla ./RRR FFF/EWRWE PPPP.BLA: No such file or directory
Can't rename ./rrr fff/wdgfaaarwe pprgr.bla ./RRR FFF/WDGFAAARWE PPRGR.BLA: No such file or directory
Can't rename ./rrr fff/wdg.qqrwe pppp.bla ./RRR FFF/WDG.QQRWE PPPP.BLA: No such file or directory
Can't rename ./rrr fff/iiuysdy wwww.bla ./RRR FFF/IIUYSDY WWWW.BLA: No such file or directory
Can't rename ./aaa fgdfg/eeeeee qqqq.bla ./AAA FGDFG/EEEEEE QQQQ.BLA: No such file or directory
Can't rename ./aaa fgdfg/zxc sss.bla ./AAA FGDFG/ZXC SSS.BLA: No such file or directory
Can't rename ./aaa fgdfg/gggg sss.bla ./AAA FGDFG/GGGG SSS.BLA: No such file or directory
zarine@zomane:~/1a-script/recrensp$ find ./ -iname "*.bla" -exec rename -v 's/\ //' "{}" \;
Can't rename ./DFg RgF/ffff dDd.bla ./DFgRgF/ffff dDd.bla: No such file or directory
Can't rename ./DFg RgF/dDFd dfdf.bla ./DFgRgF/dDFd dfdf.bla: No such file or directory
Can't rename ./rrr fff/fsfs.hhhh sfsdf.bla ./rrrfff/fsfs.hhhh sfsdf.bla: No such file or directory
Can't rename ./rrr fff/sfsd.qq.r rr.bla ./rrrfff/sfsd.qq.r rr.bla: No such file or directory
Can't rename ./rrr fff/ewrwe pppp.bla ./rrrfff/ewrwe pppp.bla: No such file or directory
Can't rename ./rrr fff/wdgfaaarwe pprgr.bla ./rrrfff/wdgfaaarwe pprgr.bla: No such file or directory
Can't rename ./rrr fff/wdg.qqrwe pppp.bla ./rrrfff/wdg.qqrwe pppp.bla: No such file or directory
Can't rename ./rrr fff/iiuysdy wwww.bla ./rrrfff/iiuysdy wwww.bla: No such file or directory
Can't rename ./aaa fgdfg/eeeeee qqqq.bla ./aaafgdfg/eeeeee qqqq.bla: No such file or directory
Can't rename ./aaa fgdfg/zxc sss.bla ./aaafgdfg/zxc sss.bla: No such file or directory
Can't rename ./aaa fgdfg/gggg sss.bla ./aaafgdfg/gggg sss.bla: No such file or directory
zarine@zomane:~/1a-script/recrensp$ for a in "`find ./ -iname "*.bla"`"; do b=`echo $a | sed 's/A-Z/a-z/g'`; mv "$a" "$b"; done
mv: cannot stat `./DFg RgF/ffff dDd.bla\n./DFg RgF/dDFd dfdf.bla\n./rrr fff/fsfs.hhhh sfsdf.bla\n./rrr fff/sfsd.qq.r rr.bla\n./rrr fff/ewrwe pppp.bla\n./rrr fff/wdgfaaarwe pprgr.bla\n./rrr fff/wdg.qqrwe pppp.bla\n./rrr fff/iiuysdy wwww.bla\n./aaa fgdfg/eeeeee qqqq.bla\n./aaa fgdfg/zxc sss.bla\n./aaa fgdfg/gggg sss.bla': No such file or directory
In this case "for a in "`find ./ -iname "*.bla"`"; do b=`echo $a | sed 's/A-Z/a-z/g'`; mv "$a" "$b"; done" new lines( \n) are also quoted and of course the result is "No such file or directory", how to quote everything else without \n .
When I using rename ( perl script ) it renames some files but some not .Strange .
...
In this case "for a in "`find ./ -iname "*.bla"`"; do b=`echo $a | sed 's/A-Z/a-z/g'`; mv "$a" "$b"; done" new lines( \n) are also quoted and of course the result is "No
That will not work because you have quoted the output of find, thereby passing only one argument to for.
If you remove the quotes, it will fail if any filenames contain whitespace or other pathological characters.
The correct way is to pipe the output of find into a while ... read ... loop.
That sed command will only replace a literal "A-Z" with "a-z".
Use tr to convert to lowercase:
Code:
find ./ -iname "*.bla" |
while IFS= read -r a
do
b=`printf "%s\n" "$a" | tr 'A-Z' 'a-z'`
mv "$a" "$b"
done"
If you are using ksh, you can save the calls to an external program with:
Code:
typeset -l b
find ./ -iname "*.bla" |
while IFS= read -r a
do
b=$a
mv "$a" "$b"
done"
Thanks, now script reading line by line, but mv still says "No such file or directory"
I put your example in script :
Code:
#!/bin/bash
find ./ -iname "*.bla" |
while IFS= read -r a
do
echo $a
b=`printf "%s\n" "$a" | tr 'A-Z' 'a-z'`
mv "$a" "$b"
done
When I run the script the result is :
Code:
./DFg RgF/ffff dDd.bla
mv: cannot move `./DFg RgF/ffff dDd.bla' to `./dfg rgf/ffff ddd.bla': No such file or directory
./DFg RgF/dDFd dfdf.bla
mv: cannot move `./DFg RgF/dDFd dfdf.bla' to `./dfg rgf/ddfd dfdf.bla': No such file or directory
./rrr fff/fsfs.hhhh sfsdf.bla
mv: `./rrr fff/fsfs.hhhh sfsdf.bla' and `./rrr fff/fsfs.hhhh sfsdf.bla' are the same file
./rrr fff/sfsd.qq.r rr.bla
mv: `./rrr fff/sfsd.qq.r rr.bla' and `./rrr fff/sfsd.qq.r rr.bla' are the same file
.
After some time :
Ehhh, of course mv always will says "No such file or directory" in this case, dir "DFg RgF" exists, but "dfg rgf" not, first I must "mkdir" it .
Use -depth when using find. This will go from the deepest to the shallowest. This will prevent you from renaming a directory which still has files yet to be renamed, which is what's happening now. The way you have it, a directory is renamed but then you try to rename a file within it using the old path name.
ta0kira
Yes, tr does a better job like cfaj said. I remembered the way to translate with sed, but you need the whole set spelled out. In case the directories are also being renamed to lowercase, here is my modified version.
Paste that into the command line and press [enter], then type the base paths and press [enter] again.
ta0kira
PS cfaj: In your solution it looks like it will turn the entire path name to lowercase, which won't work. You can only rename the basename, to be qualified by the original dirname when renaming.
FIXED: script for complex directory and file renaming
Fixnames is a GPL bash script that does recursive renaming a directories (top-level first) and files. it includes a --pretend option, full logging, simple detection of duplicate files, progress indicator.
it includes a sed line to make a tree a valid names on a fat/ntfs filesystem while removing multiple, trailing and leading spaces. it is well commented and should be easy to understand.
fixnames was developped for a mac->win migration which involved renaming of over 12k files
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.