Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
I have a bunch of files in one of three forms
This: "word.word.A#A##.word.word.foo"
or: "word.word.###.word.word.foo"
or: "### - DifferentWord"
Where # is a digit 0-9 and A is Letter (any letter) Some of the files have fewer or more words before the part with the numbers, and some of the words contain "-" and "(", ")" but are always seperated with "." and none of the file names contain spaces.
The files of the 3rd form should be left untouched.
I would rename all of these files of the first 2 forms to the form:
"### - .foo"Where ### are the same 3 digits from up above in the same order.
I figured I'd have some:
for i in (ls *.foo | sort -nr)
do
test for conditions
store 3 digits to a, b, c
mv $i $a$b$c\ -\ .foo
doneand that I could filter out the 3rd case be ignoring files containing spaces, but I'm not really sure how to go about this or how to isolate the 3 important digits.
Any ideas on how to do these two things?

Try this python script. It takes the first argument given to it (a filename in the format word.word.*#*##.word.word.foo) and renames the file to ### - .foo. If the file isn't in the format word.word.*#*##.word.word.foo, it won't be renamed.
Warning! This program doesn't check to make sure that no other files exist with the new name. If you use the same 3 digit sequence for two files, it will quietly write over the first one with the second one.
You'll want to call it from your bash script because it only handles one file at a time.
#!/usr/bin/env python
import sys
from string import find, replace
from os import renamein_file = sys.argv[1]
fw_loc = find(in_file, ".")
sw_loc = find(in_file, ".", fw_loc + 1)
tw_loc = find(in_file, ".", sw_loc + 1)
frw_loc = find(in_file, ".", tw_loc + 1)
ffw_loc = find(in_file, ".", frw_loc + 1)if ffw_loc != -1 and frw_loc != -1 and tw_loc != -1 and sw_loc != -1 and fw_loc != -1:
num = replace(in_file[sw_loc + 1:tw_loc], 'A', '')
num = replace(num, 'a', '')
ext = in_file[ffw_loc + 1:]
out_file = num + " - ." + ext
try:
rename(in_file, out_file)
except:
print "Unable to rename %s to %s" % (in_file, out_file)
sys.exit(1)
else:
print "%s doesn't match pattern *.*.*#*##.*.*.foo, so not renaming it" % in_file

This forum doesn't seem real good at keeping formatting. In python, the spacing is important, so everything between the if: and else: statements needs to be indented, as well as everything after the else: statement. Also the single line after try: needs to be indented twice, and the two lines after except: need to be indented twice.

I agree, posting code in this forum is a real *@!^*! pain.
#!/usr/bin/perl -w
while (<*.foo>) {
$nbsp$nbsp$nbsp if ($_ =~ /^[a-z]+\.[a-z]+\.[a-z](\d)[a-z](\d\d)\.[a-z]+\.[a-z]+\.foo$/i ) {
$nbsp$nbsp$nbsp # matched "word.word.A#A##.word.word.foo"
$nbsp$nbsp$nbsp$nbsp$nbsp$nbsp rename($_, "$1$2 - .foo");
$nbsp$nbsp$nbsp }$nbsp$nbsp$nbsp elsif ($_ =~ /^[a-z]+\.[a-z]+\.(\d{3})\.[a-z]+\.[a-z]+\.foo$/i ) {
$nbsp$nbsp$nbsp # matched "word.word.###.word.word.foo"
$nbsp$nbsp$nbsp$nbsp$nbsp$nbsp rename($_, "$1 - .foo");
$nbsp$nbsp$nbsp }
}

#!/usr/bin/perl -w
while (<*.foo>) {
if ($_ =~ /^[a-z]+\.[a-z]+\.[a-z](\d)[a-z](\d\d)\.[a-z]+\.[a-z]+\.foo$/i ) {
# matched "word.word.A#A##.word.word.foo"
rename($_, "$1$2 - .foo");
}elsif ($_ =~ /^[a-z]+\.[a-z]+\.(\d{3})\.[a-z]+\.[a-z]+\.foo$/i ) {
# matched "word.word.###.word.word.foo"
rename($_, "$1 - .foo");
}
}

Thanks guys! I really appreciate it! Only problem is it looks like both of those scripts only work on a fixed number of words, but the number of words is actually variable.
I went on #bash on irc.freenode.net just now and they showed me how to do replacements in bash...
So here's what I have so far:
for i in *.foo
do
#filter out letter, periods, and hyphens
x=${i//[[:alpha:]]/}
x=${x//./}
x=${x//-/}
echo "$i renames to: $x - .foo"
doneproblem that this has is that if the file name contains a space, such as "705 - foobar.foo" then i will get 3 different itterations, 705, -, and foobar.foo
I tried changing the for loop to:
for i in "$(ls *.foo)"
but that only gives me 1 $i containing ALL of the file names, each on 1 line.So I guess that's problem 1 solved. Now I just have the space in file name issue.
I can do:
mkdir spaces
mv *\ * spaces/
[run the for loop]
mv spaces/* ./
rm -r spaces/but that seems dirty and a little dangerous.

As I understand it, you’re only concerned with the 3 numbers and not the unknown number of words before or after the numbers and skip any file that is already named correctly.
So we only need to look for file names with these patterns:
“### - .foo” -> these files get skipped
“.###.” Or “.A#A##” -> these files get renamed
I don’t do any shell scripting but here’s an updated version of my prior scipt.
#!/usr/bin/perl -w
while (<*.foo>) {
    next if /^\d\d\d - .foo$/;
    rename($_, "$1$2 - .foo") if ($_ =~ /\.[a-z]?(\d)(?:[a-z])?(\d\d)\./);
}

Oh, that looks great, Fish!
Now, after the files get renamed, I manually append an arbitrary number of words (space seperated) after the hyphen.
To ignore those, too would I just change it to this?
next if /^\d\d\d -(.*).foo$/;

>> Now, after the files get renamed, I manually append an arbitrary number of words (space seperated) after the hyphen.
Why not do it in 1 step and append the words during the renaming?
>> To ignore those, too would I just change it to this?
next if /^\d\d\d -(.*).foo$/;Yes, that should work. However, I forgot 1 minor detail; we should escape the . before foo.
/^\d\d\d -(.*)\.foo$/;

![]() |
![]() |
![]() |

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |