在perl里,使用stat函数可以得到一个文件的所有属性,下面是perldoc里stat的一个列表
0 dev device number of filesystem
1 ino inode number
2 mode file mode (type and permissions)
3 nlink number of (hard) links to the file
4 uid numeric user ID of file’s owner
5 gid numeric group ID of file’s owner
6 rdev the device identifier (special files only)
7 size total size of file, in bytes
8 atime last access time in seconds since the epoch
9 mtime last modify time in seconds since the epoch
10 ctime inode change time in seconds since the epoch (*)
11 blksize preferred block size for file system I/O
12 blocks actual number of blocks allocated
stat函数的使用很简单,可以像下面这样,打印出所有属性:
1
2
3
4
5
6
7
8
9
| #!/usr/bin/perl
use strict;
use warnings;
my $filename = "/tmp/stat.pl";
for(0..12){
my $d = (stat($filename))[$_];
print "$d\n";
} |
或者也可以使用File::stat模块:
1
2
3
4
| use File::stat;
my $b = stat($filename);
printf "File is %s, size is %s, perm %04o, mtime %s\n",
$filename, $b->size, $b->mode & 07777, scalar localtime $b->mtime; |
获得unix时间:
1
2
3
4
5
| #!/usr/bin/perl
use strict;
use warnings;
print time; |
获得当前系统时间:
1
| print scalar localtime(); |
这里localtime()可带一个时间参数,默认是以当前的unix时间为参数,若要得到unix时间100秒的具体时间,可以用localtime(100)。
unix时间转换成普通的日期时间:
1
| my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); |
$sec –> 秒
$min –> 分
$hour –> 时
$mday –> 当月的第几天(1..31)
$mon –> 月(0.11)
$year –> 年(1900..,从1900年开始,所以得加上1900才能得到当前年份)
$wday –> 一周中的第几天(0是星期天,然后1..6代表周一到周六)
$yday –> 一年中的第几天(0..365)
$isdst –> 夏令时标志,如果当前时间正在使用夏令时,则$isdst为1,否则为0。
执行localtime函数得到的就是由上面这些值所组成的一个字符串。
普通的日期时间转换成unix时间
有时候为了得到两次时间间隔,把普通日期时间转换成unix时间处理起来就方便多了。
1
2
3
| use Time::Local;
my $time = timelocal($sec,$min,$hour,$mday,$mon,$year);
# replace 'timelocal' with 'timegm' if your input date is GMT/UTC |
方法很多,先介绍下我自己的方法,通过hash的键唯一性来得到不重复的元素列表,代码如下:
1
2
3
4
5
6
7
8
| #!/usr/bin/perl
use warnings;
use strict;
my @array = ("a","b","c","d","a","d","c");
my %hash;
$hash{$_}++ foreach (@array);
print sort keys %hash; |
下面是网上看到的一个方法,通过grep函数来获得不重复的元素:
1
2
3
4
5
6
7
8
| #!/usr/bin/perl
use warnings;
use strict;
my @array = ("a","b","c","d","a","d","c");
my %hash;
my @out = grep (!$hash{$_}++, @array);
print @out; |
该方法的意思是:当第一次碰到某元素$_时,$hash{$_}的值为0,!$hash{$_}为真,于是把元素$_加到数组@out中,然后把$hash{$_}值加1,这样下次再碰到同样的元素时由于!$hash{$_}此时为假,就不会写入@out数组里了,从而达到去掉重复元素的目的。
两种方法从运行效率上来看应该差不多,不过第二个感觉更炫一点。
前段时间有这么个需求,两个文件,假设是tmp1和tmp2,tmp1里有服务器序列号和服务器主机名,如下:
a 1
b 2
c 3
d 4
e 5
f 6
g 7
tmp2里则是一些无序的序列号,如下:
d
c
e
f
a
g
b
现在需要做的是按tmp2里的顺序得到它们所对应的主机名。
对于这个需求,最开始想到的就是对tmp2里的每个序列号循环,每个循环里再遍历一次tmp1的内容,从而找到需要的主机名,不过这方法当文件很大时就很慢了。所以改进了一下,把tmp1存到一个hash里,然后遍历tmp2从hash里获得需要的东西。脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #!/usr/bin/perl
use warnings;
use strict;
open(TMP1,"<tmp1") or die("error1\n");
my %hash;
while(<TMP1>){
chomp(my $tmp = $_);
my($index,$value) = split(/\s+/,$tmp);
$hash{$index} = $value;
}
close(TMP1);
open(TMP2,"<tmp2") or die("error2\n");
while(<TMP2>){
chomp(my $tmp = $_);
print $hash{$tmp}."\n";
}
close(TMP2); |
当然,这样还是麻烦了点,简单一点可以直接在命令行下就搞定了
for i in `cat tmp2`
do grep $i tmp1 | awk '{print $2}'
done
最新评论