School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 300,458 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,632 people online right now. Registration is fast and FREE... Join Now!




Perl - Using idioms and subtleties to shorten code

 

Perl - Using idioms and subtleties to shorten code

Ed_Bighead

17 Jun, 2009 - 11:19 AM
Post #1

D.I.C Head
Group Icon

Joined: 26 Apr, 2009
Posts: 166



Thanked: 14 times
Dream Kudos: 50
My Contributions
I don't know if any of you are familiar with Perl Golf, but I'm just learning some of the subtleties of the language and was wondering if you could help me shorten some code I wrote. The "one-line" script renames all jpg files in the current directory to be "pic0.jpg" "pic1.jpg" ... "pic(n).jpg" etc for all jpg files. I've written it for both windows based and unix based systems. Here it is:
Windows
perl -e "$c=0; while(`dir /B` =~ m/(\S.*\.jpg)/g) { push @a, $1} for(@a) { rename $_,'pic'.$c.'.jpg' unless (-e 'pic'.$c.'.jpg'); $c++ }"

Unix
perl -e '$c=0; while(`ls -F` =~ m/(\S.*\.jpg)/g) { push @a, $1} for(@a) { rename $_,"pic$c.jpg" unless (-e "pic$c.jpg"); $c++ }'

As a not one line command, it would look like this (for unix)
CODE
$c=0;
while(`ls -F` =~ m/(\S.*\.jpg)/g) {
    push @a, $1;
}
for(@a) {
    rename $_,"pic$c.jpg" unless (-e "pic$c.jpg");
    $c++;
}


Let me know if you have can think of any ways to shorten it. Or have a better way of approaching the problem.

User is offlineProfile CardPM
+Quote Post


KevinADC

RE: Perl - Using Idioms And Subtleties To Shorten Code

17 Jun, 2009 - 12:08 PM
Post #2

D.I.C Regular
Group Icon

Joined: 23 Jan, 2007
Posts: 401



Thanked: 25 times
Dream Kudos: 50
My Contributions
rename $_,"pic@{[$c++]}.jpg" for <*.jpg>

User is offlineProfile CardPM
+Quote Post

dsherohman

RE: Perl - Using Idioms And Subtleties To Shorten Code

18 Jun, 2009 - 02:59 AM
Post #3

D.I.C Head
**

Joined: 29 Mar, 2009
Posts: 184



Thanked: 35 times
My Contributions
QUOTE(Ed_Bighead @ 17 Jun, 2009 - 07:19 PM) *

CODE
$c=0;
while(`ls -F` =~ m/(\S.*\.jpg)/g) {
    push @a, $1;
}
for(@a) {
    rename $_,"pic$c.jpg" unless (-e "pic$c.jpg");
    $c++;
}


I'm not a golfer, but the first thing that came to mind is that your array (@a) is completely unnecessary and doesn't serve any obvious purpose beyond making the code longer.
CODE
$c=0;
while(`ls -F` =~ m/(\S.*\.jpg)/g) {
    rename $1,"pic$c.jpg" unless (-e "pic$c.jpg");
    $c++;
}

is exactly equivalent, without going through the trouble of building and reading from the array.

This can be further tightened up by looking at KevinADC's version, but note that his doesn't include the protection against clobbering existing files.
User is offlineProfile CardPM
+Quote Post

bsaunders

RE: Perl - Using Idioms And Subtleties To Shorten Code

18 Jun, 2009 - 04:15 AM
Post #4

D.I.C Addict
****

Joined: 18 Jan, 2009
Posts: 554



Thanked: 42 times
My Contributions
QUOTE(KevinADC @ 17 Jun, 2009 - 04:08 PM) *

rename $_,"pic@{[$c++]}.jpg" for <*.jpg>


Wow, that is concise. icon_up.gif
User is offlineProfile CardPM
+Quote Post

Ed_Bighead

RE: Perl - Using Idioms And Subtleties To Shorten Code

18 Jun, 2009 - 05:08 AM
Post #5

D.I.C Head
Group Icon

Joined: 26 Apr, 2009
Posts: 166



Thanked: 14 times
Dream Kudos: 50
My Contributions
QUOTE(dsherohman @ 18 Jun, 2009 - 04:59 AM) *

I'm not a golfer, but the first thing that came to mind is that your array (@a) is completely unnecessary and doesn't serve any obvious purpose beyond making the code longer.
CODE
$c=0;
while(`ls -F` =~ m/(\S.*\.jpg)/g) {
    rename $1,"pic$c.jpg" unless (-e "pic$c.jpg");
    $c++;
}

is exactly equivalent, without going through the trouble of building and reading from the array.

This can be further tightened up by looking at KevinADC's version, but note that his doesn't include the protection against clobbering existing files.


I actually tried that (I think). My problem is that `ls -F`, as well as the dir command I use for windows, lists them alphabetically. so let's say there are 3 pictures titled:
CODE
apple.jpg
car.jpg
duck.jpg
After the first iteration of the loop, the files are as follows (In alphabetic order - because that's how ls -F will show them)
CODE
car.jpg
duck.jpg
pic0.jpg
The first iteration found the first file and changed it. In the next iteration, the while loop will find the second file, which is now duck.jpg and not car.jpg, and change it.
CODE
car.jpg
pic0.jpg
pic1.jpg

During the last iteration, the script will look at pic1.jpg, but not change it b/c I told it not to. (This prevents a file overwriting a file that already exists).

@KevinADC
Now, let's say I want to all of the files that are something like "auto.*" (like auto.jpg, auto.txt, etc) and change them to "car.*" Could I just change your script to for <auto.*>? I realize I would have to change the regular expression a bit to store the file extension in $2 or something, but I'm more curious about the for loop.
User is offlineProfile CardPM
+Quote Post

KevinADC

RE: Perl - Using Idioms And Subtleties To Shorten Code

18 Jun, 2009 - 08:38 AM
Post #6

D.I.C Regular
Group Icon

Joined: 23 Jan, 2007
Posts: 401



Thanked: 25 times
Dream Kudos: 50
My Contributions
if you want to find all files in a directory that start with auto then yes, you can use <auto*>.

On a more practical note, the glob() function is better used in perl code than the <*> type glob.
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic

Time is now: 11/8/09 02:09AM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month