?

Log in

No account? Create an account
entries friends calendar profile Elf Sternberg's Pendorwright Projects Previous Previous Next Next
Another useful chunk of code: rn - Elf M. Sternberg
elfs
elfs
Another useful chunk of code: rn
Another piece of blindingly useful code (although in this case one that will help you cut your leg off at the knee if you're not careful), this is a program I use every freaking day, it seems like. rn is a little script that takes as its first argument a pcre regular expression, usually held between two single quotes, and then a list of files.

When it's done, the file names will all have been modified according to the expression. For example, let's say you have a bunch of files named, "Album - Artist - Song.mp3" and you want them named "Artist - Album - Song.mp3". You would type in:

rn 's/Album - Artist/Artist - Album/' *.mp3

Or, if you were feeling fancy:

rn 's/^(.*?) - (.*?) - /$2 - $1 - /' *.mp3

This makes in-place mass-revision of filenames very easy.

 #!/usr/bin/perl

($op = shift) || die "Usage: $0 perlexpr [filenames]\n";

if (!@ARGV) {
    @ARGV = <STDIN>;
    chop(@ARGV);
}

foreach (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was, $_) unless ($was eq $_);
}

Current Mood: geeky geeky
Current Music: Synergy, Breakdown in World Communication

10 comments or Leave a comment
Comments
From: technoshaman Date: March 31st, 2005 10:39 pm (UTC) (Link)
I only have one problem with that script.

To me, it's forever hardwired that "rn" means "read news". And being a serious command-line junkie, if I ever *were* to read Usenet ever again, I would probably use.... rn.

I'd probably name it mmv.

But other than that? Perfectly fine, and a legitimate use of Perl, being as Perl, for all it's being an almost write-only language, has some pretty darn fine regexp code...
elfs From: elfs Date: April 1st, 2005 12:28 am (UTC) (Link)
It's a little over my limit (being, that is, ten lines or less), but it's good for its job. I've gotten used to 'rn' being 'rename', mostly because I started with TRN and I use Gnus anyway.

It can use one (rather major) fix. It should not rename until it has done a "-f" test on the default scalar; I've once or twice blown away quite a number of files by repeatedly renaming them all to the same thing.

From: lazarus834 Date: April 1st, 2005 11:52 pm (UTC) (Link)
I'm using a debian distro which comes with a script called "rename".... Which is pretty much the same idea. It's a perl script.



_candide_ From: _candide_ Date: April 1st, 2005 02:42 am (UTC) (Link)
Bah. There are no write-only programming languages... only write-only code.
I've seen both horrid, write-only code and literate-programming in just about every language.

Programming languages are still languages. And, like any other written human language, you can express yourself coherently in it, or ramble incoherent, unreadable nonsense.

Perl is no more or less "inherently unreadable" than French is more or less "inherently logical." Any statements to the contrary are purely a matter of personal taste.
abostick59 From: abostick59 Date: April 1st, 2005 03:39 am (UTC) (Link)
Never coded any APL, I take it?
elfs From: elfs Date: April 1st, 2005 04:54 am (UTC) (Link)
I only partially disagree. A scatter chart of languages with one axis labeled "popularity" and the other labeled "ability to write code badly" would have perl as an outlier high in the upper-left-hand corner. It is simply easy to write bad perl code, by anyone.

It is hard for a beginner to write bad python. (It's easier if you have years of experience in perl, though, like I do.)
_candide_ From: _candide_ Date: April 3rd, 2005 03:29 am (UTC) (Link)
It is hard for a beginner to write bad python. (It's easier if you have years of experience in perl, though, like I do.)
Oh come now, Elf, that's like saying, "It's hard for a beginner to write bad German." It's not hard at all for a beginner to write bad Python. All they have to do is write enough of it.

Any programming language, written by a novice with a poor enough understanding of that languages principles and, yes, writing style, will be badly written. That bad style will become all-too-obvious when they start writing a large python program, because that program will be very hard to read.

In the tehcnical journals, I've seen more than one suggestion for how to improve programming. They always end up failing, because they are one-size-fits-all suggestions. Plus, there's also a bit of, "G*d will build a better idiot," at work, too. ;)

If you can write complex expressions in a language, you can write unreadable code. And any language you can't use for complex code is pretty damn useless, ne? Hence my assertion.

My main problem with Python, the way it becomes unreadable for me, is the very feature that most laud as making it "inherently" readable: syntactic whitespace. I have poor eyesight, you see, so I can't make my screen resolution 1600x1200 so my editor is 300 chars wide. Ever try reading a very long, complex conditional, with linebreaks put in not by good writing style, but by the finite width of a screen or sheet of paper? Not Fun. Turn off the line-wrapping, and I get motion sick from the constant back-and-forth horizontal scrolling.

If you force the indentation width, make it and blank lines part of the syntactic structure, you guarantee 200-500 char lines. I ultimately abandoned my attempt to learn Python because of this. All of the existing Python scripts I tried to use as learning examples were just too hard on my eyes, and if I can't write complicated expressions that don't cause me eye-strain, then the code is unreadable.

And you have to admit, also, that a lousy programmer won't have the good sense to break apart a long, complex function into several functions solely for the sake of improving its readability.

But the Python guys almost got it right, IMNSHO. What they should've done, instead of making whitespace syntactic, was to keep '{ }' blocks and variable indentation, but do something else. Something new: put a style guide in the compiler. Don't try to enforce a fixed, one-size-fits-all style, but howl loudly about known bad-style gaffs. Indentation containing mixed whitespace (not all tabs, not all spaces). Conditionals containing too many multiple subconditionals (like, more than 5) crammed onto the same line. Add a few compiler-options to turn on stronger style checking, as needed. Like inconsistent indentation within a single block. One-char variables outside of loop indices. Had they done this, they would've been hailed as revolutionary geniuses, and every other language would be doing this as well.

Since I'm critiquing Python, it's only fair that I do so to Perl, as well. :) Perl is the bastard love-child of the Bourne-shell and C. It's a weird hybrid of scripting and structured-procedural programming languages, with a poorly-designed object model kludged on. But the other problem with Perl objects really boils down to one of familiarity.

But the other complaint people have about Perl --- regexps --- has nothing to do with Perl. Regexps are hard. Hard to write. Hard to read. Yet very powerful. Regexps will separate those who can write software from those who think they can write software. :)
fallenpegasus From: fallenpegasus Date: April 1st, 2005 11:09 pm (UTC) (Link)

Allow me to suggest


#!/usr/bin/perl
 
($op = shift) || die "Usage: $0 perlexpr [filenames]\n";
 
if (!@ARGV) {
    @ARGV = ;
    chomp(@ARGV);
}
 
foreach (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    if (-e $_) {
	print "wont overwrite existing $_ with $was\n";
	next;
    }
    $ok = rename($was, $_) unless ($was eq $_);
    $ok or print "fail rename($was, $_): $!\n";
}





It uses the safer chomp instead of chop, it won't overwrite an existing file, and it reports OS errors that rename() may encounter.
fallenpegasus From: fallenpegasus Date: April 1st, 2005 11:11 pm (UTC) (Link)

Re: Allow me to suggest

Sigh, LJ ate everything between angle brackets, and I can't edit a comment.

#!/usr/bin/perl
 
($op = shift) || die "Usage: $0 perlexpr [filenames]\n";
 
if (!@ARGV) {
    @ARGV = <STDIN>;
    chomp(@ARGV);
}
 
foreach (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    if (-e $_) {
	print "wont overwrite existing $_ with $was\n";
	next;
    }
    $ok = rename($was, $_) unless ($was eq $_);
    $ok or print "fail rename($was, $_): $!\n";
}
fallenpegasus From: fallenpegasus Date: April 1st, 2005 11:14 pm (UTC) (Link)

A useful varient. Downcase filenames.

This can be done with your script, but it do it often enough I have this special case.
#!/usr/bin/perl

if (!@ARGV) {
    @ARGV = <STDIN>;
    chomp(@ARGV);
}

foreach (@ARGV) {
    $was = $_;
    tr/A-Z/a-z/;
    # tr/_/-/;
    if (-e $_) {
	print "wont overwrite existing $_ with $was\n";
	next;
    }
    $ok rename($was, $_) unless $was eq $_;
    $ok or print "fail rename($was, $_): $!\n";

}
10 comments or Leave a comment