LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   specific file name renaming in all sub directories (https://www.linuxquestions.org/questions/linux-newbie-8/specific-file-name-renaming-in-all-sub-directories-872906/)

Jack_R 04-04-2011 11:48 AM

specific file name renaming in all sub directories
 
Hello,

I have a dir (pub_html) with 45 sub dirs, and in each there is a file with name (file123.html) what command can I use to rename all files with this name in all sub dirs to file456.html ?
I'm on opensuse 11.3

grail 04-04-2011 11:57 AM

man find
man mv

Jack_R 04-04-2011 02:38 PM

I tried that
 
Quote:

Originally Posted by grail (Post 4313573)
man find
man mv

Well I tried that but can't really figure out how to combine the commands .. it would be helpful if I can get a specific command answer.

grail 04-04-2011 09:25 PM

Well what have you tried? Remember the idea is we are here to assist and not necessarily do the work for you.

I will assume that after 'man mv' you are comfortable with how to rename a file using this command?

As far as find goes, did you check out the EXAMPLES (not shouting here ... this is what you can search for) section?

Essentially you need the following:

1. starting directory
2. check out -type to limit to files (ie so you don't rename a directory)
3. -name (or one of the many derivatives to suit your needs) will need to be passed the type of file you are looking for (eg. .txt, .mp3, .avi, etc)
4. redirect this into a loop (suggest while loop)

I also noted that you are using Ubuntu. This being the case you may also wish to 'man rename' which would then change step 4. to:

4. check out -exec to have rename alter file.

Within the rename man page i would also look at the '-n' option as a test scenario (ie to check results are as expected before making change)

Let us know if you get stuck?

Jack_R 04-05-2011 04:01 PM

grail, thanks for your advice, this is what I came up with:
find /path -name 'filename' | while read file ;do ; newfile=${filename%}".xml" ; mv $file $newfile ; done

what am I doing wrong here ?

chrism01 04-05-2011 07:03 PM

What errors are you getting?
you could try something like (not the exact soln)
Code:

set -xv
for oldfile in $(find /path -type f -name '*123.html')
do
    #amend filename here : http://www.tldp.org/LDP/abs/html/refcards.html#AEN22102

    # show old & new names
    echo $oldfile $newfile
done

and try in a test area with just a small num of files. The 'set -xv' is the debugger; it prints out everything as it happens; very informative.

NB: 1st post is html files, now you're talking xml ....?

bigrigdriver 04-05-2011 07:34 PM

Yet another way to do it (isn't Linux wonderful?):
Code:

#Recursively rename some to other
for FILE in `find . -name file123.html`
do
NEW=`echo $FILE | sed -e 's/123/456/'`
mv "$FILE" "$NEW"
done

or, replacing the backticks with $():
Code:

#Recursively rename some to other
for FILE in $(find . -name file123.html)
do
NEW=$(echo $FILE | sed -e 's/123/456/')
mv "$FILE" "$NEW"
done

Note the use of find to find the file with the file123.html pattern, then piping through sed to replace 123 with 456.

I didn't originate the script. I found it using www.google.com/linux and searching for find mv rename. I also found many others, but this one seemed the most elegant.

grail 04-06-2011 03:24 AM

Quote:

find /path -name 'filename' | while read file ;do ; newfile=${filename%}".xml" ; mv $file $newfile ; done
So in /path you are looking for files called filename and passing the output to the while loop.

The loop now reads each line (remembering that find will not only return the filename but the full path from /path) into the variable file.

Unfortunately you then in your code to set the newfile name reference what you are searching for and not what you have found:
Code:

newfile=${filename%}".xml"

#should be
newfile=${file%}".xml"

Of course the example you have provided is not as complicated as your original request as you are only changing the extension here.
Hence why the examples provided by others are a little more complex.

Jack_R 04-06-2011 05:49 AM

Quote:

NB: 1st post is html files, now you're talking xml ....?
chrism01, there are about 31k files in total in those folders, all of which are .html, Im trying to change a specific name out of those .html to .xml with a differend file name, so when the 'find' finds oldfile.html it will change it to newname.xml

chrism01, bigrigdriver, grail, I have tried all of your commands in various ways but no luck:

1 example:

Jack@opsu:/opt/lampp/htdocs/html/Ready/socal/> for FILE in $(find . -name oldfile.html)
> do
> NEW=$(echo $FILE | sed -e 's/oldfile.html/newfile.xml/')
> mv "$FILE" "$NEW"
> done
Jack@opsu:/opt/lampp/htdocs/html/Ready/socal/>

nothing happens...

jschiwal 04-06-2011 06:12 AM

The -printf command in find can be used to generate scripts to do what you want.

This example will find files named 1234.html and rename them to 5678.html
find ./ -name 1234.html -printf 'mv -v %p %h/5678.html\n' >renamescript

You can review the script before executing, to prevent any surprises. For example, if a directory name has spaces in it, maybe using -printf 'mv -v "%p" "%h/5678.html"\n' >renamescript
would be useful.

grail 04-06-2011 06:16 AM

You do realise that executing an mv command does not have any output?
You can test it by the following:
Code:

$ touch file1
$ mv file1 file2

After both of the above commands you will be at the command prompt and there will be no output.

I would first suggest you go and look for the file 'oldfile.html' to see if it still exists. Assuming it existed prior to running the script it
should now obviously be 'newfile.xml'

Should you wish to see some output you can use the '-v' switch with mv to get verbose output.

Jack_R 04-06-2011 07:10 AM

Quote:

find ./ -name 1234.html -printf 'mv -v %p %h/5678.html\n' >renamescript
this actually finds the files and seems like it will rename but at the moment it simply logs what it should do to "renamescript" file in that directory.

Quote:

$ touch file1
$ mv file1 file2
when Im runing this I get an error:
If '$' is not a typo you can use command-not-found to lookup the package that contains it, like this:
cnf $

BTW - Thanks for all your help people.

grail 04-06-2011 07:54 AM

$ - this is simply the prompt ... ie it is not something to be typed

Quote:

logs what it should do to "renamescript"
Correct, but if you read the rest of the post that came from:
Quote:

You can review the script before executing
So the idea is that you now execute 'renamescript' to make the changes

Jack_R 04-06-2011 09:10 AM

Great, that did exactly what I needed :) thank you for all your help guys.

grail 04-06-2011 11:29 AM

Well I am glad you got it working. Just thought I would show you what i meant based on your original example:
Code:

find /path -type f -name 'file123.html' -exec rename 's/123/456/' {} \;


All times are GMT -5. The time now is 12:07 PM.