views:

545

answers:

7

I have hundreds of text files in a folder named using this kind of naming convention:

Bandname1 - song1.txt
Bandname1 - song2.txt
Bandname2 - song1.txt
Bandname2 - song2.txt
Bandname2 - song3.txt
Bandname3 - song1.txt
..etc.

I would like to create folders for different bands and move according text files into these folders. How could I achieve this using bash, perl or python script?

A: 

How about this:

for f in *.txt
do
  band=$(echo "$f" | cut -d'-' -f1 | trim)
  if [ -d "$band" ]
  then
    mkdir "$band"
  fi
  mv "$f" "$band"
done
gregseth
Thanks, but my Bash (I'm on mac 10.6.2) says that -bash: trim: command not foundI tried textutil::text but I got same answer
jrara
A: 

You asked for a specific script, but if this is for organizing your music, you might want to check out EasyTAG. It has extremely specific and powerful rules that you can customize to organize your music however you want:

alt text

This rule says, "assume my file names are in the structure "[artist] - [album title]/[track number] - [title]". Then you can tag them as such, or move the files around to any new pattern, or do pretty much anything else.

John Feminella
A: 

gregseth's answer will work, just replace trim with xargs. You could also eliminate the if test by just using mkdir -p, for example:

for f in *.txt; do
    band=$(echo "$f" | cut -d'-' -f1 | xargs)
    mkdir -p "$band"
    mv "$f" "$band"
done

Strictly speaking the trim or xargs shouldn't even be necessary, but xargs will at least remove any extra formatting, so it doesn't hurt.

bjlaub
A: 
ls |perl -lne'$f=$_; s/(.*?) - [^-]*\.txt/$1/; mkdir unless -d; rename $f, $_/$f'
J.F. Sebastian
A: 

This Python program assumes that the source files are in data and that the new directory structure should be in target (and that it already exists).

The key point is that os.path.walk will traverse the data directory structure and call myVisitor for each file.

import os
import os.path

sourceDir = "data"
targetDir = "target"

def myVisitor(arg, dirname, names):
    for file in names:
        bandDir = file.split("-")[0]
        newDir = os.path.join(targetDir, bandDir)
        if (not os.path.exists(newDir)):
            os.mkdir(newDir)

        newName = os.path.join(newDir, file)
        oldName = os.path.join(dirname, file)

        os.rename(oldName, newName)

os.path.walk(sourceDir, myVisitor, None)
Michael Easter
+3  A: 

It's not necessary to use trim or xargs:

for f in *.txt; do
    band=${f% - *}
    mkdir -p "$band"
    mv "$f" "$band"
done
Dennis Williamson
+1 for not using external tools
ghostdog74
band=${f% - *}, no?
pra
@pra: Yes, thanks.
Dennis Williamson
+1  A: 

with Perl

use File::Copy move;
while (my $file= <*.txt> ){
    my ($band,$others) = split /\s+-\s+/ ,$file ;
    mkdir $band;
    move($file, $band);
}
ghostdog74