LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Renaming multiple files from filnames within a text file (https://www.linuxquestions.org/questions/linux-newbie-8/renaming-multiple-files-from-filnames-within-a-text-file-790664/)

lt1776 02-21-2010 09:59 PM

Renaming multiple files from filnames within a text file
 
Here is the situation. I have some random files in a folder. I want to rename all of the files in a batch process. I have a text file that contains the CURRENTname of all the files in the folder, as well as a text file with all of the NEWname of files in the folder. I want to replace CURRENTnames with NEWnames.

For example, here are the names of the files in the folder:
1.mp4
2.mp4
3.mp4

I have a text file with the CURRENTname of all the files in the folder:
1.mp4
2.mp4
3.mp4

I have a text file with the proper NEWname of the file:
a.mp4
b.mp4
c.mp4

I want to rename CURRENTname with NEWname in the folder. So when I go to the folder the NEWname of the files are:
a.mp4
b.mp4
c.mp4

Does anybody know how to accomplish this. I tried to use a nested loop but couldn't figure out how to do it.

jschiwal 02-21-2010 10:23 PM

How many files are you talking about. Loading each file into a pair of array variables and using the values of each in a single loop will do the trick.

You can read a file into a variable like this:
orignames=($(cat names.txt))
propnames=($(cat propernames.txt))

You can use ${#orignames[*]} to get the number of entries in the arrays. Use a single loop where you reference both variables with the same index.

lt1776 02-22-2010 07:17 AM

Ok, can you give me an example of the loop. I am not sure how to create the loop formula. I have never done a pair array. Thanks.

onebuck 02-22-2010 07:24 AM

Hi,

So you've shown us your need! What's your deed?

Smells like homework to me.

Just a few links to aid you, the two in red will provide some useful information but you will have to do the work;

Linux Documentation Project
Rute Tutorial & Exposition
Linux Command Guide
Utimate Linux Newbie Guide
LinuxSelfHelp
Getting Started with Linux
Advanced Bash-Scripting Guide
Linux Home Networking

:hattip:
The above links and others can be found at 'Slackware-Links'. More than just SlackwareŽ links!

lt1776 02-22-2010 12:20 PM

lol - whatever. I work full time in finance and have never taken a programming class in my life. I am in the works to make a script that downloads youtube videos in mass. I need to find out how to rename the file w/ the proper name.

For some reason, when you use youtube-dl the option to use the friendly name as the name of the file is broken and doesn't work. So when i download the video using youtube-dl the name of the file is the URL ID. Something like "CndjgDnwo.mp4"

I can make two text files, one with the name of the file and the other with the correct name of the file.

Thanks for the links though. I will check them out.

colucix 02-22-2010 12:40 PM

A very rough but (I think) effective solution can be: use the paste command to put the file names side by side, add "mv" at the beginning of each line using sed, save the output to a file (script), carefully check it and run. Easier done than said:
Code:

paste -d' ' CURRENTname.txt NEWname.txt | sed 's/^/mv /' > test.sh
# Check the content of test.sh and if you're satisfied...
bash test.sh

Anyway, trying to find out how to solve the issue by following the advices from jschiwal and onebuck, could be a very interesting and fruitful experience. As to say... learn the art and set it aside. :)

lt1776 02-22-2010 12:56 PM

Nice- the paste command works perfect. Thanks

lt1776 02-22-2010 01:04 PM

Can someone explain how do implement the solution provided by jschiwal

Quote:

You can read a file into a variable like this:
orignames=($(cat names.txt))
propnames=($(cat propernames.txt))

You can use ${#orignames[*]} to get the number of entries in the arrays. Use a single loop where you reference both variables with the same index.

chrism01 02-22-2010 05:43 PM

Start here: http://tldp.org/LDP/abs/html/arrays.html

lt1776 02-23-2010 12:54 PM

Ok, I am getting an error. Here is the sample problem I am working with:
List of files:
a.txt
b.txt
c.txt

File with CURRENT file names:
old

Contents of old:
a.txt
b.txt
c.txt

File with NEW file names:
new

Contents of new:
abby.txt
barry.txt
cindy.txt

My script is as follows:
old=$(cat old)
new=$(cat new)

#$old now contains 'a.txt b.txt c.txt'
#$new now contains 'abby.txt barry.txt cindy.txt'

for file in *.txt; do mv $old $new; done

=======================================
After the I run the commands I get an error:
mv: target `cindy.txt' is not a directory
mv: target `cindy.txt' is not a directory
mv: target `cindy.txt' is not a directory


Does anybody know what I am doing wrong?

chrism01 02-23-2010 05:14 PM

He's prompting you to use arrays; see my link above.

whizje 02-23-2010 05:51 PM

You are trying to rename all the files at one.

Code:

while read line; do
    mv $line;
done < <(paste curr.txt new.txt)

You need to feed mv with 1 line at a time.

lt1776 02-23-2010 10:17 PM

Quote:

Originally Posted by chrism01 (Post 3874331)
He's prompting you to use arrays; see my link above.

I read over the link and did some of the exercises. I still don't understand how I can use a pair array to rename all the files. How would you use the array formula to do that?

I already tried:
for file in *.txt; mv $old $new; done

However, I can't get that to work. I am just a beginner and am just learning as I go. Any help on how to use a pair array to rename files would be helpful.

colucix 02-24-2010 04:52 AM

The problem with your solution is what whizje already pointed out, two posts above. The loop
Code:

for file in *.txt
do
  mv $old $new
done

is dummy, since it doesn't use the loop variable "file" in its body. Furthermore upon the shell substitution of the two variables "old" and "new" with their values, you end-up with a command line like this:
Code:

mv a.txt b.txt c.txt abby.txt barry.txt cindy.txt
that is not as expected and wrong, since you can move multiple files at once, but only when the last argument is the name of a directory (the destination).

Regarding the array solution, jschiwal already provided it in post #2. You have just to translate its words into shell code. Here is a working example of what you can obtain..

1) first assign the content of the two files to two different arrays (as shown above)
Code:

orignames=( $(cat old) )
propnames=( $(cat new) )

here we use command substitution $(command) to retrieve the content of the files, and array assignment using parentheses.

2) do a loop over the array indexes, but take in mind that they are zero-based, that is the first index is 0, the second one is 1 and so on...
Code:

for ((i=0; i < ${#orignames[*]} ; i++))
do
  echo mv ${orignames[i]} ${propnames[i]}
done

here I used a C-style for loop (which is permitted in bash), but you can try a different syntax and even a while loop, if you prefer. The syntax ${#orignames[*]} returns the length of the array, as you already should know. The echo statement is just for testing purposes (it prints out the command without actually executing it).

Hope this helps. Keep up your learning process from the basics and you will see that at some point you will spare a lot of time to accomplish both simple and complex tasks.

lt1776 02-24-2010 12:27 PM

I appreciate the tutorial. I am beginning to understand how it works not. Works perfect. Thanks colucix


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