UBB.Dev
Posted By: HelloWorld Regular Expressions - 04/22/2001 7:57 AM
Ok heres the deal, I am trying to parse the 'LIST' output of any unix directory. A file entry goes something like this:

drwx------ 5 anpatel students 512 Jan 13 2000 Desktop

Simple way of getting each field is:
my @properties = split(/s+/,$line);

But this code has one specific flaw. What if the file was "New Text Document.txt", there would be no way saying that $properties[9] was the full name of the file. I thought of improving the code:

my @properties = split( /s+/, $item );
my ( $perms, $lCount, $owner, $group, $size, $mod_mon, $mod_date, $mod_time ) = @properties;
my $file = join( "", @properties[8.. $#properties] );

But $file will be "NewTextDocument.txt" because the &join will compine all the rest of array elements with "".

I was looking for a perfect solution if some one could offer, of-course i am on the hunt. But lets see if some one figures out before me wink hehehe

Thanks for reading this!
Posted By: Mark Badolato Re: Regular Expressions - 04/22/2001 8:31 AM
do you need all of the properties, or just a list of filenames?
Posted By: HelloWorld Re: Regular Expressions - 04/22/2001 8:46 PM
Basically i need all the properties, but to be exact i need:

if the file is directory ($perms, $properties[0])
File Size ($size, $properties[4])
File Mod Time ( none, $properties[5... 7] )
File name ($file, $properties[8..*])

hmm i think you are suggesting me to use the simple 'ls' command, and find all the file names easily from that, I had this in mind, but dont want to use it (for many reasons)
Posted By: HelloWorld Re: Regular Expressions - 04/22/2001 8:58 PM
hmm.. if we might locate somehow with Regexps, the char number of where the file name starts than bingo!.

But sadly i am still trying to find that way out.
Posted By: Dave_L Re: Regular Expressions - 04/23/2001 1:15 AM
Instead of trying to parse the text output of a Unix command, I'd recommend using readdir to scan through the files, and stat to get the file properties.
Posted By: HelloWorld Re: Regular Expressions - 04/23/2001 3:27 AM
Thanks, but I am trying to parse the FTP list output, there is no way of readdir() in a FTP client, however there is a ftp->ls() command, that gives you only file name output, but there are no specific ways to merge that information to the ftp->dir() output.

The only choice that is left now is to effectively parse the LIST output.

Thanks for replying!
Posted By: HelloWorld Re: Regular Expressions - 04/23/2001 4:01 AM
I did it!!!, i figured out that since we know at what field we need to stop, we just eliminate the fields before what we want. Sorry for bothering ya'all


my $str = "drwx------ 3 anpatel students 512 Apr 18 14:45 Really Bad Name Name for a file.";

$str =~ s/Ss+//; #1 perms-links
$str =~ s/Ss+//; #2 links-user
$str =~ s/Ss+//; #3 user-grp
$str =~ s/Ss+//; #4 grp-apr
$str =~ s/Ss+//; #5 apr-date
$str =~ s/Ss+//; #6 date-time
$str =~ s/Ss+//; #7 time-filename
$str =~ s/^(S+)s+(.*)/$2/; # remove all the things that were combined previously. result is we get the file name!
print $str;
exit;
Posted By: AllenAyres Re: Regular Expressions - 05/09/2005 8:24 AM
Quote
Originally posted by Dave_L:

Instead of trying to parse the text output of a Unix command, I'd recommend using readdir to scan through the files, and stat to get the file properties.
How would stat be used after you've read the directory and would like to read/print file names, date, and size?
Posted By: AllenAyres Re: Regular Expressions - 05/09/2005 9:48 PM
found some answers:

http://aspn.activestate.com/ASPN/docs/ActivePerl/lib/File/stat.html
Posted By: Burak Re: Regular Expressions - 05/09/2005 10:10 PM
so, you no longer have a question? smile
Posted By: AllenAyres Re: Regular Expressions - 05/09/2005 10:34 PM
Still have questions, but that at least tells me the reasoning behind the answer smile

I can probably write it using the example posted, I'll write back when I have questions.

Basically we readdir then use stat to be able to print the file size ($size) and date ($mtime). $filename gives me the file's name?

Would something like this be in the right direction?

Code
use File::stat;

($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
then use $filename, $mtime, and $size for the data I'm looking for?
Posted By: Burak Re: Regular Expressions - 05/09/2005 10:48 PM
File::stat gives you a by-name access to stat() values (actually it returns an object). If you'll not use them, just use the CORE stat function (which returns an array)... Else, something like this will work:

Code
my @files = <*.txt>; # all txt in current dir
my $stat;
foreach my $file (@files) {
$stat = stat $file or die "Error: $!";
printf "%st%st%sn", $file, format_size($stat->size), format_time($stat->mtime);
}
Posted By: AllenAyres Re: Regular Expressions - 05/09/2005 11:16 PM
thank you, that should do it smile

So in the final print line $file will give me the filename?
Posted By: Burak Re: Regular Expressions - 05/10/2005 12:07 AM
yes $file includes file name or full path to the file... depending on your usage...
Posted By: AllenAyres Re: Regular Expressions - 05/10/2005 8:16 AM
How does this look?

Code
opendir(UPLOADS, "$opt{dir}/$user_number");
my @uploads = readdir(UPLOADS);
closedir(UPLOADS);
my @files = <*.txt>; # all txt in current dir
my $stat;
foreach my $file (@files) {
$stat = stat $file or die "Error: $!";

##output it

print qq(
<tr valign="top">
<td bgcolor="$vars_style{AltColumnColor2}" align="center" width="20"><input type="checkbox" name="$key" value="include" checked="checked" /></td>
<td bgcolor="$vars_style{AltColumnColor2}"><b><font size="$vars_style{FDTextSize}">$filename</font></b></td>
<td bgcolor="$vars_style{AltColumnColor2}" align="center" valign="middle">$size</td>
<td bgcolor="$vars_style{AltColumnColor2}" align="center" valign="middle">$mtime</td>
</tr>
);
}
It's not throwing an error, but then it's not reading/printing anything either tipsy

How would I fix the section to view all files, not just .txt?

Thank you again for your time smile
Posted By: Burak Re: Regular Expressions - 05/10/2005 1:52 PM
txt one was an example (or demo) on the usage smile use this:

Code
opendir(UPLOADS, "$opt{dir}/$user_number") or die "Can not opendir($opt{dir}/$user_number): $!";
my @uploads = readdir(UPLOADS);
closedir(UPLOADS);
my($size, $mtime);
foreach my $filename (@uploads) {
next if $filename =~ /^./; # ignore anything that starts with a dot. like "." ".." ".htaccess"
($size, $mtime) = (stat "$opt{dir}/$user_number/$filename")[7,9] or die "Error: $!";

##output it

print qq(
<tr valign="top">
<td bgcolor="$vars_style{AltColumnColor2}" align="center" width="20"><input type="checkbox" name="$key" value="include" checked="checked" /></td>
<td bgcolor="$vars_style{AltColumnColor2}"><b><font size="$vars_style{FDTextSize}">$filename</font></b></td>
<td bgcolor="$vars_style{AltColumnColor2}" align="center" valign="middle">$size</td>
<td bgcolor="$vars_style{AltColumnColor2}" align="center" valign="middle">$mtime</td>
</tr>
);
}
it is always better to see the actual code smile
Posted By: AllenAyres Re: Regular Expressions - 05/10/2005 3:16 PM
yay, we're getting there:

https://www.ubbdev.com/ubbcgi/ubb_fileman.cgi

thumbsup
Posted By: Burak Re: Regular Expressions - 05/10/2005 3:52 PM
no problem... but you need to swap "Date:" "Size:" texts smile and... I can give you a byte converter smile

Code
sub fsize {
my $size = shift or return '0 byte';
return sprintf("%1.2f %s",$size / 1024 / 1024 / 1024, " GB" ) if($size >= 1024*1024*1024);
return sprintf("%1.2f %s",$size / 1024 / 1024 , " MB" ) if($size >= 1024*1024 );
return sprintf("%1.2f %s",$size / 1024 , " KB" ) if($size >= 1024 );
return sprintf("%1.2f %s",$size , " Byte") if($size < 1024 );
return "$size Byte";
}
so, you can use it like:

Code
opendir(UPLOADS, "$opt{dir}/$user_number") or die "Can not opendir($opt{dir}/$user_number): $!";
my @uploads = readdir(UPLOADS);
closedir(UPLOADS);
my($size, $mtime);
foreach my $filename (@uploads) {
next if $filename =~ /^./; # ignore anything that starts with a dot. like "." ".." ".htaccess"
next if -d "$opt{dir}/$user_number/$filename"; # ignore directories
($size, $mtime) = (stat "$opt{dir}/$user_number/$filename")[7,9] or die "Error: $!";

##output it
$size = fsize($size);

print qq(
<tr valign="top">
<td bgcolor="$vars_style{AltColumnColor2}" align="center" width="20"><input type="checkbox" name="$key" value="include" checked="checked" /></td>
<td bgcolor="$vars_style{AltColumnColor2}"><b><font size="$vars_style{FDTextSize}">$filename</font></b></td>
<td bgcolor="$vars_style{AltColumnColor2}" align="center" valign="middle">$size</td>
<td bgcolor="$vars_style{AltColumnColor2}" align="center" valign="middle">$mtime</td>
</tr>
);
}
Posted By: Burak Re: Regular Expressions - 05/10/2005 3:57 PM
hey! I've just noticed the cake! laugh Happy Birthday! thumbsup
Posted By: AllenAyres Re: Regular Expressions - 05/10/2005 6:18 PM
grazi, I'm not getting older, I'm getting... well, ok, I'm getting older tipsy
Posted By: BLESSY JOSE Re: Regular Expressions - 09/15/2005 3:40 PM
May be this looks a bit more appropriate

my $str = "drwx------ 3 anpatel students 512 Apr 18 14:45 Really Bad Name Name for a file.";

$str =~ s/(S)s/$1/; #1 perms-links
$str =~ s/(S)s/$1/; #2 links-user
$str =~ s/(S)s/$1/; #3 user-grp
$str =~ s/(S)s/$1/; #4 grp-apr
$str =~ s/(S)s/$1/; #5 apr-date
$str =~ s/(S)s/$1/; #6 date-time
$str =~ s/(S)s/$1/; #7 time-filename
$str =~ s/^(S+)s+(.*)/$2/; # remove all the things that were combined previously. result is we get the file name!
print $str,"n";
© UBB.Developers