fasoli has asked for the wisdom of the Perl Monks concerning the following question:
Hi Wise Monks!
Happy 2016!
I have a question regarding the "touch" function in Perl as I think that it may be suitable for my case. EDIT: Sorry, I forgot to add that I haven't succeeded in using the File::Touch function as I get an error message when I try to run the script (can't locate in @inc), so I will use Unix's touch command.
I am writing a script for data handling that will loop through a variety of files and do a variety of things. What I'm stuck with now is the following: I want to be able to check what step of my calculations is completed, the step is written in the filename. So let's say that the latest file I have is step S00005. This means I'll want to check if the previous step, S00004, exists (I think by using if -e), and then, if it exists, remove S00004 and prepare a new input file that has the number ST006. The idea is that the "previous step" will always exists as a backup.
I have read this page about touch http://metacpan.org/pod/distribution/ppt/bin/touch
#/bin/perl/ use strict; use warnings; my $results = "~/results"; my $unpacked = "~/results/unpacked"; my $submit = "~/submit"; my @files; @files = `ls *$txt`; my $filename; my $seq; my $nr; my $mol; my $dir; my $step; my $type; open (my $finished, '>>', "finished.txt"); printf $finished ("%-5s%12s%14s","Molecule","Structure","Step"); printf $finished "\n"; close $finished; foreach (@files) { /(prefix)(_)(\d+)(_)(\d+)(_)(\w+)(_)(\w+)(_)(\w+)(\.)(\w+)/; $filename = "$1$2$3$4$5$6$7$8$9$10$11$12$13"; print "name of file: $filename \n"; print "\n"; $seq= $3; $nr = $5; $mol = $7; $dir = $9; $step = $11; $type = $13; open (my $finished, '>>', "finished.txt"); printf $finished ("%-5s%15s%15s",$mol,$dir,$step); printf $finished "\n"; close $finished; my $check = 0; $check = `ls | grep -c $mol\_$dir\_step\.$out`; print "$mol\_$dir\_$step\.$out: $check \n"; if ($check == 0) { open my $error, '>>', 'error.txt'; print $error "WARNING $mol\_$dir\_$step\.$out is missing \n"; close $error; } else { open my $found, '>>', 'found.txt'; printf $found "$mol\_$dir\_$step\.$out is found \n"; close $found; } $check = 0; print `rsync -ravn \*$mol\_$dir\_$step\.$out ~/results/unpacked/$ +mol/$dir`; ###this is where my problems start my @step = ( step( 'S', 6, 1, 5 ), ); for $step (@step) { print `touch $step`; } sub step { my ( $name, $total_length, $from, $to ) = @_;# my $length = $total_length - length($name); my $format = "${name}%0${length}d"; return map sprintf( $format, $_ ), $from .. $to; } if (`ls -c *$step*`) { print "$step is found \n" } else { print "$mdstep not found \n" } }
So what I've done so far is that I check for the relevant files that exist, print error/found messages and copy the files over to the directory where I will process them.
Then, at the "this is where my problems start" bit is where I have mixed everything up. What I want to do is tell Perl to look for the latest (hence the, hopefully correct, ls -c) file number in the S00001 or S00002 or S00003 and so on files. So if the latest one is S00003, I want to check if S00002 exists. If it exists, I want to remove it and touch S00004.
In my code above, I tried to implement what a Monk here taught me (the subroutine use and format) but I haven't implemented it correctly/usefully. I only wanted to test how the touch function is used and that's why I tried it out. But at this point it's not useful. What is useful, is manage to use ls -c properly.
So what mostly confuses me is what to use instead of the variable $step in `ls -c *$step*` as this just lists all of them. How do I do "ls -c S00010" for example, if I knew that the latest file I had was file 10???
I would honestly appreciate any help and hints and resources as I've been stuck for hours now.
Thank you all in advance and I'm sorry if my message is confusing (especially the subroutine bit that I only tried to see how touch works), if people feel that my message is too confusing I'll try to edit it.
|
|---|