Mansueli
Mansueli

Reputation: 6994

Python usage of os.renames

I am trying to rename files using python but I cannot figure exactly where is the error, perhaps I am too tired as trying to do this for over 30 hours non-stopping.

The actual problem is quite visible when you look at the desired output and in the actual one.

#!/usr/bin/env python
import sys
import os
import glob
if __name__ == '__main__':
    input_file=sys.argv[1]
    File= open(input_file)
    while True:
       line=File.readline()
       words = line.split()
       if not ("call" or "song") in words:
         break 
       folder_dest= words[0] +" "+ words[1]
       subfolder=words[3]
       filename=words[4].replace(".wav","")
       folder_now=words[7].replace(".wav","")
       os.chdir(folder_now)
       i=1
       for files in glob.glob("*.wav"): 
           os.renames(files,"../"+folder_dest+"/"+subfolder+"/"+filename+"-"+'{:03}'.format(i)+".wav")
           i+=1
       os.chdir("..")

More explanation:

I have this input file

Aegolius harrisii song 10009.wav Aegolius harrisii song 21.wav
Aegolius harrisii song 483_Aegolius%20harrisii_F27_Itatira_28_IV_2004_Weber%20Girao.wav Aegolius harrisii song 22.wav
Gnorimopsar chopi song 1000517.wav Gnorimopsar chopi song 825.wav
Myiobius barbatus call Myiobius.sulphureipygius9402-1.wav Myiobius barbatus call 1146.wav
Myiobius barbatus song 1001.wav Myiobius barbatus song 1147.wav
Muscipipra vetula call 1000682.wav Muscipipra vetula call 1122.wav

This is the current folder structure:

1
├── parte_1.wav
└── parte_2.wav

2
├── parte_1.wav
├── parte_2.wav
├── parte_3.wav
├── parte_4.wav
├── parte_5.wav
└── parte_6.wav

...

Here is the output as now:

Aegolius harrisii/
    ├── 100015.wav
    │   ├── Aegolius-001.wav
    │   └── Aegolius-002.wav
    └──  AEGOLI~1.wav
        ├── Aegolius-001.wav
        ├── Aegolius-002.wav
        ├── Aegolius-003.wav
        ├── Aegolius-004.wav
        ├── Aegolius-005.wav
        └── Aegolius-006.wav

desired output

Aegolius harrisii/
├── call
│   ├── 100015-001.wav
│   └── 100015-002.wav
└── song
    ├──  AEGOLI~1-001.wav
    ├──  AEGOLI~1-002.wav
    ├──  AEGOLI~1-003.wav
    ├──  AEGOLI~1-004.wav
    ├──  AEGOLI~1-005.wav
    └──  AEGOLI~1-006.wav

The question is: what I'am doing wrong in os.renames?

Thank you, for reading/answering this!

Upvotes: 2

Views: 765

Answers (1)

abarnert
abarnert

Reputation: 365953

The first problem is obvious if you just print out words:

['Aegolius', 'harrisii', 'song', '10009.wav', 'Aegolius', 'harrisii', 'song', '21.wav']

You're setting subfolder=words[3], which is 10009.wav rather than song. You wanted the third word, which is words[2] (because Python is 0-based).

Likewise, you're setting filename=words[4] instead of words[3], which is Aegolius rather than 10009.wav.

I think you have folder_now correct—it's 21.wav.


The second problem is that if not ("call" or "song") in words doesn't do what you want. ("call" or "song") is just "call". So, you're stopping as soon as you reach a line with song in it.

You probably wanted this:

if not ("call" in words or "song" in words):

… or maybe:

if not {"call", "song"}.intersection(words):

A third possible problem (I don't know if this is affecting you) is that you use break instead of continue, which means you stop at the first invalid line, instead of just skipping over invalid lines.


While we're at it, a few minor ways you could improve your code:

  • Be consistent with your indentation. Your source mixes tabs and spaces, which is a recipe for disaster; you're lucky you got away with it. You also use different amounts of indentation everywhere—two spaces, three spaces, four spaces, one tab, etc.—which makes your code hard to read. Find yourself an editor that takes care of this for you (whether that's IDLE, a fancy IDE like Visual Studio or Eclipse, a nice "programmer's text editor" like BBEdit, or even emacs).
  • Instead of doing while True: and line=File.readline(), you can just do for line in File:.
  • Don't try to os.chdir down and back up. You'll leave things in a funky state if you fail or cancel in the middle, you'll run into problems with symlinks, etc. You can just use paths, like for files in glob.glob(os.path.join(folder_now, "*.wav")).
  • Use os.path functions instead of trying to treat paths as strings.
  • Don't try to maintain an explicit counter by setting i=1 and doing i+=1 each time through the loop; just use enumerate.
  • Use consistent naming conventions.

Upvotes: 1

Related Questions