Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to perform unix command within perl script?

Status
Not open for further replies.
Apr 30, 2003
56
0
0
US
The purpose of my script is to go through a directory of all the files. Look at the creation date for those files. Say for example, if a file is created in 2008, I will create a 2008 folder under the directory and move the file into the new 2008 folder and loop through the whole directory with all the files. But one thing I am not so sure is how to read the date for the files? And how can I perform the unix mkdir and mv command inside the perl script?

The directory files listed as follows:
-rw-r--r-- 1 oracle dba 248608 Oct 2 2007 relnote_stnd_18.fle
-rw-r--r-- 1 oracle dba 350187 Oct 15 2007 relnote_stnd_19.fle
-rw-r--r-- 1 oracle dba 296794 Oct 15 2007 relnote_stnd_20.fle
-rw-r--r-- 1 oracle dba 154456 Oct 23 2007 relnote_stnd_21.fle
-rw-r--r-- 1 oracle dba 140559 Oct 23 2007 relnote_stnd_22.fle


#!/usr/bin/perl

opendir (DIR, "/dsk01/oradata/rtest/udump");
foreach my $file (readdir(DIR)) {
next if $file =~ /^\./; #skip ., .., etc
(Need to know who to read the date and perform unix command.)

}
closedir (DIR);

Please Advice. Thank you very much.
 
Hi

eileen1017 said:
But one thing I am not so sure is how to read the date for the files?
[tt]stat[/tt] to get the Unix time, then [tt]localtime[/tt] to get the year.
eileen1017 said:
And how can I perform the unix mkdir and mv command inside the perl script?
[tt]mkdir[/tt].

Personally I find it ugly to call external commands from Perl.
Perl:
[gray]#!/usr/bin/perl[/gray]

[b]use[/b] File[teal]::[/teal]Copy[teal];[/teal]

[b]opendir[/b] DIR[teal],[/teal] [green][i]"/dsk01/oradata/rtest/udump"[/i][/green][teal];[/teal]
[b]foreach[/b] [b]my[/b] [navy]$file[/navy] [teal]([/teal][b]readdir[/b] DIR[teal])[/teal] [teal]{[/teal]
  [b]next[/b] [b]if[/b] [navy]$file[/navy] [teal]=~[/teal] [green][i]/^\./[/i][/green][teal];[/teal] [gray]# skip ., .., etc[/gray]
  [b]next[/b] [b]unless[/b] [teal]-[/teal]f [navy]$file[/navy][teal];[/teal] [gray]# skip non-files[/gray]

  [navy]@stat[/navy] [teal]=[/teal] [b]stat[/b] [navy]$file[/navy][teal];[/teal]
  [navy]@time[/navy] [teal]=[/teal] localtime [navy]$stat[/navy][teal][[/teal][purple]9[/purple][teal]];[/teal]
  [navy]$year[/navy] [teal]=[/teal] [navy]$time[/navy][teal][[/teal][purple]5[/purple][teal]][/teal] [teal]+[/teal] [purple]1900[/purple][teal];[/teal]
  [b]unless[/b] [teal](-[/teal]d [navy]$year[/navy][teal])[/teal] [teal]{[/teal]
    [b]mkdir[/b] [navy]$year[/navy] or [b]die[/b] [green][i]"Error creating directory '$year' : $!"[/i][/green][teal];[/teal]
  [teal]}[/teal]
  copy [navy]$file[/navy][teal],[/teal] [green][i]"$year/$file"[/i][/green] or [b]die[/b] [green][i]"Error copying file '$file' : $!"[/i][/green][teal];[/teal]
[teal]}[/teal]
[b]closedir[/b] DIR[teal];[/teal]


Feherke.
 
Hi Feherke:

Thanks for your reply. The copy command that you used in your script, does it work the same as unix mv command? The reason I am asking is that I want to move the files to a new folder. Not just copy the files to the folder and leave the original alone.
Another thing, if the date shows the current year, then I am not going to do anything. How do you filter that out?
 
Hi

Oops. No idea why I had the feeling you want to copy.

For elementary file moving the [tt]rename[/tt] function is usually enough, but there is a robust [tt]move[/tt] implemented in the same [tt]File::Copy[/tt] module.
Perl:
[gray]#!/usr/bin/perl[/gray]

[b]use[/b] File[teal]::[/teal]Copy[teal];[/teal]

[highlight][navy]@today[/navy] [teal]=[/teal] localtime[teal];[/teal][/highlight]
[highlight][navy]$thisyear[/navy] [teal]=[/teal] [navy]$today[/navy][teal][[/teal][purple]5[/purple][teal]][/teal] [teal]+[/teal] [purple]1900[/purple][teal];[/teal][/highlight]

[b]opendir[/b] DIR[teal],[/teal] [green][i]"/dsk01/oradata/rtest/udump"[/i][/green][teal];[/teal]
[b]foreach[/b] [b]my[/b] [navy]$file[/navy] [teal]([/teal][b]readdir[/b] DIR[teal])[/teal] [teal]{[/teal]
  [b]next[/b] [b]if[/b] [navy]$file[/navy] [teal]=~[/teal] [green][i]/^\./[/i][/green][teal];[/teal] [gray]# skip ., .., etc[/gray]
  [b]next[/b] [b]unless[/b] [teal]-[/teal]f [navy]$file[/navy][teal];[/teal] [gray]# skip non-files[/gray]

  [navy]@stat[/navy] [teal]=[/teal] [b]stat[/b] [navy]$file[/navy][teal];[/teal]
  [navy]@time[/navy] [teal]=[/teal] localtime [navy]$stat[/navy][teal][[/teal][purple]9[/purple][teal]];[/teal]
  [navy]$year[/navy] [teal]=[/teal] [navy]$time[/navy][teal][[/teal][purple]5[/purple][teal]][/teal] [teal]+[/teal] [purple]1900[/purple][teal];[/teal]
  [highlight][b]next[/b] [b]if[/b] [navy]$year[/navy] [teal]==[/teal] [navy]$thisyear[/navy][teal];[/teal][/highlight]
  [b]unless[/b] [teal](-[/teal]d [navy]$year[/navy][teal])[/teal] [teal]{[/teal]
    [b]mkdir[/b] [navy]$year[/navy] or [b]die[/b] [green][i]"Error creating directory '$year' : $!"[/i][/green][teal];[/teal]
  [teal]}[/teal]
  [highlight]move[/highlight] [navy]$file[/navy][teal],[/teal] [green][i]"$year/$file"[/i][/green] or [b]die[/b] [green][i]"Error [highlight]mov[/highlight]ing file '$file' : $!"[/i][/green][teal];[/teal]
[teal]}[/teal]
[b]closedir[/b] DIR[teal];[/teal]

Feherke.
 
Hi feherke:

When I try to execute the script that you provided, I got the following message:
./move_trace_rtest.perl[10]: use: not found
./move_trace_rtest.perl[11]: @today: not found
./move_trace_rtest.perl[12]: =: not found
./move_trace_rtest.perl[13]: syntax error at line 13 : `(' unexpected

Another question regarding your script is that if there are more than one file that was created in the same year. Is your code going to create a folder every time, it found that year?
 
Hi

It works for me :
Code:
[blue]master #[/blue] for ((i=2010;i<=2012;i++)); do touch -d "$i-01-01" "file-$i.txt"; done

[blue]master #[/blue] ls -l
total 4
-rwxr--r-- 1 master users 506 Apr 27 19:29 eileen1017.pl*
-rw-r--r-- 1 master users   0 Jan  1  2010 file-2010.txt
-rw-r--r-- 1 master users   0 Jan  1  2011 file-2011.txt
-rw-r--r-- 1 master users   0 Jan  1 00:00 file-2012.txt

[blue]master #[/blue] ./eileen1017.pl 

[blue]master #[/blue] ls -l
total 4
drwxr-xr-x 2 master users  80 Apr 27 19:29 2010/
drwxr-xr-x 2 master users  80 Apr 27 19:29 2011/
-rwxr-xr-x 1 master users 506 Apr 27 19:29 eileen1017.pl*
-rw-r--r-- 1 master users   0 Jan  1 00:00 file-2012.txt

[blue]master[/blue] # tree 
.
|-- 2010
|   `-- file-2010.txt
|-- 2011
|   `-- file-2011.txt
|-- eileen1017.pl
`-- file-2012.txt

2 directories, 4 files
How and where are you executing that script ?
eileen1017 said:
Another question regarding your script is that if there are more than one file that was created in the same year. Is your code going to create a folder every time, it found that year?
No. The [tt]unless [teal](-[/teal]d [navy]$year[/navy][teal])[/teal][/tt] condition makes sure to not call the [tt]mkdir[/tt] if the directory already exists.


Feherke.
 
Ok. I fixed the message problem. I moved #!/usr/bin/perl to the first line above all my comments. The scripts executed without any message. But the directory didn't get created. Maybe it is because my script is residing at a separate directory than those files are actually are? Let me move my script to that directory and try again.
 
Hi

eileen1017 said:
The scripts executed without any message. But the directory didn't get created. Maybe it is because my script is residing at a separate directory than those files are actually are? Let me move my script to that directory and try again.
Yes, seems to be a path problem, but more likely with the destination path. The script moves things to the same directory it was executed from.

Changing the directory is one solution, but personally I prefer to explicitly specify the full path everywhere. Supposing you want the yearly subdirectories to be under the source directory ( like /dsk01/oradata/rtest/udump/2011 ) :
Perl:
[gray]#!/usr/bin/perl[/gray]

[b]use[/b] File[teal]::[/teal]Copy[teal];[/teal]

[navy]$dir[/navy] [teal]=[/teal] [green][i]'/dsk01/oradata/rtest/udump'[/i][/green][teal];[/teal]

[navy]@today[/navy] [teal]=[/teal] localtime[teal];[/teal]
[navy]$thisyear[/navy] [teal]=[/teal] [navy]$today[/navy][teal][[/teal][purple]5[/purple][teal]][/teal] [teal]+[/teal] [purple]1900[/purple][teal];[/teal]

[b]opendir[/b] DIR[teal],[/teal] [navy]$dir[/navy][teal];[/teal]
[b]foreach[/b] [b]my[/b] [navy]$file[/navy] [teal]([/teal][b]readdir[/b] DIR[teal])[/teal] [teal]{[/teal]
  [b]next[/b] [b]if[/b] [navy]$file[/navy] [teal]=~[/teal] [green][i]/^\./[/i][/green][teal];[/teal] [gray]# skip ., .., etc[/gray]
  [b]next[/b] [b]unless[/b] [teal]-[/teal]f [green][i]"$dir/$file"[/i][/green][teal];[/teal] [gray]# skip non-files[/gray]

  [navy]@stat[/navy] [teal]=[/teal] [b]stat[/b] [green][i]"$dir/$file"[/i][/green][teal];[/teal]
  [navy]@time[/navy] [teal]=[/teal] localtime [navy]$stat[/navy][teal][[/teal][purple]9[/purple][teal]];[/teal]
  [navy]$year[/navy] [teal]=[/teal] [navy]$time[/navy][teal][[/teal][purple]5[/purple][teal]][/teal] [teal]+[/teal] [purple]1900[/purple][teal];[/teal]
  [b]next[/b] [b]if[/b] [navy]$year[/navy] [teal]==[/teal] [navy]$thisyear[/navy][teal];[/teal]
  [b]unless[/b] [teal](-[/teal]d [green][i]"$dir/$year"[/i][/green][teal])[/teal] [teal]{[/teal]
    [b]mkdir[/b] [green][i]"$dir/$year"[/i][/green] or [b]die[/b] [green][i]"Error creating directory '$year' : $!"[/i][/green][teal];[/teal]
  [teal]}[/teal]
  move [green][i]"$dir/$file"[/i][/green][teal],[/teal] [green][i]"$dir/$year/$file"[/i][/green] or [b]die[/b] [green][i]"Error moving file '$file' : $!"[/i][/green][teal];[/teal]
[teal]}[/teal]
[b]closedir[/b] DIR[teal];[/teal]

Feherke.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top