update: renaming a bunch of files AND directories in linux

skyking

Lifer
Nov 21, 2001
22,368
5,330
146
I need to rename about 70 files, simple stripping off the cpmove- from the front of them in a redhat server. how would I go about that as a batch?

Update:
How about fixing those blasted directories? Things like "my documents" and "program files" are inaccessible by the usual method.
 

oog

Golden Member
Feb 14, 2002
1,721
0
0
for f in cpmove-*; do mv $f `echo $f | sed s/cpmove-//` ; done;

essentially, look for all files that match the pattern cpmove-*, and then execute the mv command where the target is determined by substituting taking the filename and passing it to a sed script which will switch "cpmove-" with nothing.

there are probably better ways to do this. i'm only picking up linux again after being away from *nix for about 10 years.
 

drag

Elite Member
Jul 4, 2002
8,708
0
0
Dammit. I figured out a way, only to come back and get beaten to the punch. Well here is another way using echo.


ls cpmove-* | while read i ; do mv "$i" `echo "${i:7}"` ; done

Oh, well. I can take solice is the fact that mine will work with filenames with spaces, his won't.

BTW People who use spaces in names should be banned from their computer and re-educated on the fine art of file naming.
 

skyking

Lifer
Nov 21, 2001
22,368
5,330
146
hear hear!!! one of my pet peeves when I make a samba server, and my buddies do not understand that all the songs with the cute spaces in the title are a real PAIN!!
 

drag

Elite Member
Jul 4, 2002
8,708
0
0
stick this in crontab to run every 5 minutes...

find /share/mnt | grep \ |while read i; do mv "$i" "${i// /_}"; done

Carefull of home directories .* user configuration directories will often have spaces in config names deep in them.
 

skyking

Lifer
Nov 21, 2001
22,368
5,330
146
I wanted to thank you all again. I could have "man"ed and googled my way to this stuff, but only after a great deal of trial and error. So far, I have used every suggestion given.
I have also started using "cat root" to read root's mail on servers that are not overwhelmed with root mail, and then "cat /dev/null>root" to empty it out later. That is, if I have not taken the time to alias out out to another account, or if the server is not a mailserver
 

uOpt

Golden Member
Oct 19, 2004
1,628
0
0
No need to invoke sed or friends, the shell can strip parts of a string in a variable on its own. It also removes the trouble with spaces in filenames.

for file in cpmove-* ; do mv -i "$file" "${file#cpmove-}" ; done
# the quoting also ensure it works for filenames with spaces

Actually I do stuff like this this way:

for file in cpmove-* ; do echo mv -i $file ${file#cpmove-} ; done
# check result
# then fire for effect
for file in cpmove-* ; do echo mv -i $file ${file#cpmove-} ; done | sh

Needs additional quoting for filenames with spaces, but I usually solve that by
rm *\ *
 

uOpt

Golden Member
Oct 19, 2004
1,628
0
0
Originally posted by: drag
Dammit. I figured out a way, only to come back and get beaten to the punch. Well here is another way using echo.


ls cpmove-* | while read i ; do mv "$i" `echo "${i:7}"` ; done

Oh, well. I can take solice is the fact that mine will work with filenames with spaces, his won't.

This boombs for filename with backslaces in them, and can actually enable users to execute commands under your id.

You need `read -r`.

It also doesn't handle space correctly, you lose space at the beginning and the end of the resulting filename:
touch cpmove-\ 2
~/ll(schlepper)41% ls cpmove-* | while read i ; do mv "$i" `echo "${i:7}"` ; done
~/ll(schlepper)42% ls
2

Note "2" should be " 2".
 

drag

Elite Member
Jul 4, 2002
8,708
0
0
This boombs for filename with backslaces in them, and can actually enable users to execute commands under your id.


how would it allow users to execute commands under my ID? The system won't even allow you to setuid for bash scripts, its ignored... I don't understand.

(also if you have some reason why you would want spaces in the beginning and end of file names i would be happy to hear about it.)
 

uOpt

Golden Member
Oct 19, 2004
1,628
0
0
Originally posted by: drag
This boombs for filename with backslaces in them, and can actually enable users to execute commands under your id.

how would it allow users to execute commands under my ID? The system won't even allow you to setuid for bash scripts, its ignored... I don't understand.

I mean if you, under your ID (or as root) rename a bunch of files that somebody else created, e.g. if you do that from a cronjob like you said above.

(also if you have some reason why you would want spaces in the beginning and end of file names i would be happy to hear about it.)

I can't even think of reasons to have them in the middle, but actual users and reason don't meet often

 

drag

Elite Member
Jul 4, 2002
8,708
0
0
I mean if you, under your ID (or as root) rename a bunch of files that somebody else created, e.g. if you do that from a cronjob like you said above.

Can you give a example of a file name that would execute a command?
 

uOpt

Golden Member
Oct 19, 2004
1,628
0
0
Originally posted by: drag
I mean if you, under your ID (or as root) rename a bunch of files that somebody else created, e.g. if you do that from a cronjob like you said above.

Can you give a example of a file name that would execute a command?

Hm, it's more difficult than I thought. I was thinking you could at least alias an existing file with a backshlash-newline combination, causing the wrong file to me moved. But order of evaluation ensures that the unalised file gets chosen, so it doesn't allow you to insert wrong file contents.

I retract that claim.

You still need `read -r`, otherwise you will make parts of the move fail. I don't see anymore how to exploit that, though.
 

drag

Elite Member
Jul 4, 2002
8,708
0
0
Good to know though. I spent a while trying to figure out how to screw it up... Worst thing you can do that I figured out is if you put a - or a -- in a file name you can trick it into passing arguements to the command, which may cause some havoc...

So it's probably not the best idea to run these things as root, you would have to run these things with a user permissions of a special user or something.
 

bofkentucky

Member
Nov 8, 2004
28
0
0
If your command in the cron job ends in [space] -- [space] , which is harmless, you will be safe from an expliot such as this.


Oh and for an example, try this

touch "i[space]`rm -rf /`[space]just_wiped_the_disk_with_a_mv.txt"; mv *.txt /backups

!Do not do this on a live system!


Never trust user input!

 

drag

Elite Member
Jul 4, 2002
8,708
0
0
touch "i[space]`rm -rf /`[space]just_wiped_the_disk_with_a_mv.txt"; mv *.txt /backups

That's still not quite right, I think...

When you run the first part of the command, the "touch" part, that's when your running the rm -rf /, not the mv part.

The `` inside the "" is the part being executed. So if I tried to make that file using your command I would of just ended up at most deleting my own files, and leaving the system otherwise unmolested.

If you want to make that filename properly you have to encase it in ' ' single qoutes because those override the `` qoutes. To do it properly with double qoutes " " you have to add all these \ before the ` ` and the spaces. The single qoutes will take the formatting directly.

Except that touch won't let you put / in your filename anyways. It just keeps on saying "no such file or directory", which pisses me off a bit. It should allow you to do that if you format the command correctly, but it doesn't for some reason. You can put in a * though.

To correctly do what I think your trying to do you would go:
touch i\ \`rm\ \-rf\ \*\`\ just_wiped_the_disk_with_a_mv.txt; mv *txt backup/
or
touch 'touch i `rm -rf *` just_wiped_the_disk_with_a_mv.txt'; mv *txt backup/

And both of those work fine....

 

skyking

Lifer
Nov 21, 2001
22,368
5,330
146
This has been an informative thread. How about renaming directories? The ones with spaces are inaccessible. How would it be possible to rename them?
 

drag

Elite Member
Jul 4, 2002
8,708
0
0
Found a quick sort-of answer at a blog here

His script is:
#!/bin/sh
ls | grep " " > /tmp/list$$
while read i
do
fnew=`echo "$i" | sed 's/ /_/g'`
mv "$i" $fnew
done < /tmp/list$$
rm /tmp/list$$

That will do it for all files.
However if you want directories only then you can add a if then statement based on the file command...
#!/bin/sh
ls | grep " " > /tmp/list$$
while read i
do
fnew=`echo "$i" | sed 's/ /_/g'
if file '$i' |grep directory > /dev/null
then`
mv "$i" $fnew
fi
done < /tmp/list$$
rm /tmp/list$$

Or something like that. Probably want to test it out!!! (I didn't.)
If you want it to work recursovely you can use find instead of ls and I think that will work. Although I probably wouldn't do that to be on the safe side. just one directory at a time, unless of course I had a few hundred directories to deal with. (also wouldn't work with any files with the word "directory" as part of their names. probably fix that with a quick pipe thru awk before the grep)

Probably bad advice, but that's my first idea.
 

uOpt

Golden Member
Oct 19, 2004
1,628
0
0
Again, the "read" solutions fail short of expectations in multiple ways. See my earlier posts.

The above also needlessly creates a tempfile and fails to remove it if the scripts is interrupted.

Recursively doing this creates a reliance on proper ordering. If you rename a dir all the filenames and dirname in there becomes inaccessible with previously discovered filename, so you need a strict depth-first approach.

Also, the above fails when there are two directories with names that are only different in spaces, e.g. "foobar" and "foo bar". Renaming the latter to the former won't work, you would have to intelligently merge the contents of the directory. Then you face problems of what to do with files that exist under the same name in both dirs.

To do this waterproof you cannot just kill the spaces or you will create aliasing problems. You would have to declare a "magic" character that must not appear in filenames or gets aliased first, then you use special sequences for your to-be-killed characters and for real occurrences of your magic character.

At some point it becomes easier to fix all the scripts to deal with filenames with spaces instead of renaming everything.

Very obviously, if you rename the Windows files stored filenames on Windows will stop working, e.g. "last opened" menus, shortcuts on desktops and the like.
 

drag

Elite Member
Jul 4, 2002
8,708
0
0
Give me a example with the read command, please. I want to see how you'd use it in a situation like this.

Examples are cool.
 

uOpt

Golden Member
Oct 19, 2004
1,628
0
0
You mean without the read command?

Doing this recusively with potentially renaming directories is actually not trivial. I have a scripts to totally lowercase all filenames in a tree but it is not perfect either
 
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |