前言:第十章是讲更多的控制结构方面,是之前的一个完善,第11和12章主要讲目录文件方面的操作,有SHELL基础的会发现很多都可以和SHELL中的一些命令对比,甚至是一样的。学习到12章这本书已经只有1/5了,再过4章就完结了,算是有个大概的了解的,最后一篇笔记就是最后四章了。
第十章 更多控制结构 1、unless 控制结构 在条件为假时执行 跟if 相反 也可以用unless ...else 但这种情况最好还是用if ... else 2、until 控制结构 跟while循环条件部分取反 until($j > $i){ $j *=2; } 只是在条件为假时重复执行,而不是在条件为真的情况下执行。 3、表达式修饰符 print "$n is a negative number.\n" if $n<0; 简写的形式读起来很像英文:输出这段消息,如果$n 小于 0。 跟下面是一样的 if($n < 0){ print "$n is a negative number.\n"; } 4、The Naked Block 控制结构 裸块 { body; body; body; } 5、elsif语句 elsif,只有一个 e。 6、自增和自减 自增运算符(++)会使标量变量自动加1,这和 C 以及类似语言是一样的: $bedrock++; #$bedrock 的值加1; 自减运算符(--)将标量变量的值减 将++放在变量前,先将此变量增1,再取其值。这是前置++ my $m = 5; my $n = ++$m;#$m 的值增加到6,将此值赋给$n my $d = $m++; #$d 得到先前的值(5)然后自增到6 my $e = $m--; #$e 得到先前的值(6),再自减到5 7、for控制结构 for 循环的最常用用法是,进行重复的运算: for($i =1; $i <=10; $i++){ print "I can count to $i;\n"; } #从1到10 关键字 foreach 和 for 是等价的。 8、循环控制 last 操作 last 会立刻结束循环和C语言中的break类似 #输出所有出现 fred 的行,直到遇见 _ _END_ _标记 while(<STDIN>){ if(/_ _ END_ _/){ #这个标记之后不会有其它输入了 last; }elsif(/fred/){ print; } } ##last 跳转到这里## last 常用在最内层的循环体中,可以从中跳到外面来; next 操作 它跳到当前循环块的最后面(块内)。next 之后,又会进入下一轮循环(这和 C 或者类似语言的 "continue"相似) 循环控制的第三个操作是 redo。它会调到当前循环块的顶端,不进行条件表达式判断以及接着本次循环。 next 和 redo 的最大区别在于,next 会进入下一次循环,而 redo 会继续执行本次循环。 9、 标签块 标签在 Perl 中就像一般标识符一样:由字母,数字,下划线组成,但不能由数字开头。 推荐标签均大写。这会防止标签和其它标识符冲突,同时也使之在代码中更突出。同时,标签很少使用, LINE: while(<>){ oreach (split){ last LINE if /_ _END_ _/; #推出 Line 循环 … } } 10、 逻辑操作符 逻辑判断的逻辑与 AND(&&)和逻辑或 OR (||): 11、短路操作的值 短路操作的结果是最后被执行语句的返回值,而非仅仅是一个 Boolean 值。结果是相同的。如果最后被执行的部分为真,则整个为真;为假,则整个为假。 12、 三元操作符 ?: 三元操作有些像 if-then-else 一样,不过是在一个表达式之中。被称作“三元”操作符是因为它有三个操作数,看起来如下: Express ? if_true_expr : if_false_expr 13、 控制结构:使用部分求值的操作符 前面三个操作符 &&, || , ?:,均有一个共同的特殊性质:根据左侧的值(true 或 false),来判断是否执行右侧代码。 第十一章 文件检验 1、文件检测操作 使用-e 选项 die "Oops! A file called '$filename' already exists.\n" if -e $filename; 选项 含义 -r 文件或目录对此(有效的)用户(effective user)或组是可读的 -w 文件或目录对此(有效的)用户或组是可写的 -x 文件或目录对此(有效的)用户或组是可执行的 -o 文件或目录由本(有效的)用户所有 -R 文件或目录对此用户(real user)或组是可读的 -W 文件或目录对此用户或组是可写的 -X 文件或目录对此用户或组是可执行的 -O 文件或目录由本用户所有 -e 文件或目录名存在 -z 文件存在,大小为 0(目录恒为 false) -s 文件或目录存在,大小大于 0(值为文件的大小,单位:字节) -f 为普通文本 -d 为目录 -l 为符号链接 -S 为 socket -p 为管道(Entry is a named pipe(a "fifo")) -b 为 block-special 文件(如挂载磁盘) -c 为 character-special 文件(如 I/O 设备) -u setuid 的文件或目录 -g setgid 的文件或目录 -k File or directory has the sticky bit set -t 文件句柄为 TTY(系统函数 isatty()的返回结果;不能对文件名使用这个测试) -T 文件有些像“文本”文件 -B 文件有些像“二进制”文件 -M 修改的时间(单位:天) -A 访问的时间(单位:天) -C 索引节点修改时间(单位:天) 2、 stat 和 lstat 函数 要得到文件的其余信息,可以使用 stat 函数,其返回 Unix 系统调用 stat 时相同的值 $dev 和 $ino 文件的设备号和索引节点号。 $mode 文件的权限位以及一些其它的位。 $nlink 文件或目录的(硬)连接数。 $uid 和 $gid 指文件所有权的 user ID 及 group ID。 $size 返回其大小,单位:字节,同 – 文件检测项相同。 $atime, $mtime, 及 $ctime 这三个时间,它们按照系统的时间格式:32 位 当 stat 的参数是符号连接时,其返回的信息是此符号连接指向的实体的信息,而非符号连接本身的信息,除非此符号连接所指向的内容不能被访问。 。如果需要得到(几乎是没用的)符号连接本身的信息,可以使用 lstat 代替 stat(它按照相同的顺序返回同样的值)。如果其操作数不是符号连接,则 lstat 和 stat 返回的值相同。 3、 localtime 函数 。gmtime 函数同 localtime 一样,除了其返回的形式为是世界时间(曾经被叫做格林威治时间)。如果想从系统中得到当前的时间,可使用 time 函数。localtime 和 gmtime 在默认的情况下都使用 time 的当前值,如果没提供参数: my $now = gmtime; #得到当前的时间 4、位操作 按位与操作符(&)返回操作符左边和右边相应位操作的结果。 10 & 12 按位与; 10 | 12 按位或; 10 ^ 12按位异或; 6 << 2位左移, 25 >> 2位右移, ~10 位取反, 5、使用位串 所有的 使用特殊的下划线文件句柄 第十二章 目录操作 1、在目录树上移动 chdir改变工作目录 类似Shell的cd 命令 chdir "/etc" or die "cannot chdir to /etc: $!"; 2、由于尖括号的含义可以指从文件句柄读入或 globbing,Perl 怎么判断使用哪一个操作呢?如果尖括号之间是一个严格意义 上的标识符,则其为文件句柄读入操作;否则,为 globbing 操作。如下例: my @files = <FRED/*>; ##glob my @lines = <FRED>; ##文件句柄读入 my $name = "FRED"; my @files = <$name/*> ##glob 3、目录句柄 从给定目录得到其文件名列表的方法还可以使用目录句柄(directory handle) 打开(使用 opendir 而非 open),从中读入(使用 readdir 而非 readline),关闭(使用 closedir 而非 close) my $dir_to_process = "/etc"; opendir DH, $dir_to_process or die "Cannot open $dir_to_process: $!"; foreach $file(readdir DH) { print "one file in $dir_to_process is $file\n"; } closedir DH; 这些列表含有所有的文件名,包括点(.)文件,以及由点(.)开头,或点点(..)开头的文件名 readdir 操作返回的文件名没有路径名部分,而只是文件名。 得到的不是/etc/passwd 而是 passwd。 4、 递归的目录列表 File::Find 的库,通过它你可以对递归的目录进行处理。 5、删除文件 在 Perl 中,我们使用 unlink: unlink "slate","bedrock","lava"; 等价 $ rm slate bedrock lava unlink glob "*.o"; 等价 rm *.o 返回值 如果数字为 3(个数),则它将所有的三个文件均删除了,如果为 0,则一个也没删除。 6、重命名文件 rename "old","new"; 类似Shell中的mv 甚至可以在不同的目录之间操作就跟mv的功能一样 怎样将所有的以.old 结尾的文件重名命名为以 .new 结尾的文件。 foreach my $file (glob "*.old"){ my $newfile = $file; $newfile =~ s/\ .old$/.new/; if (-e $newfile){ warn "can't rename $file to $newfile: $newfile exists\n"; }elsif(rename $file, $newfile){ ##成功,什么也不做 } else { warn "rename $file to $newfile failed: $!\n"; } } 7、连接和文件 符号连接。(也被叫做软连接(soft link),以区别于真或硬连接(hard links))是目录中的一种特殊实体 link "chicken","egg" or warn "Can't link chicken to egg: $!"; shell 提示符后输入 ln chicken egg 的结果是差不多的。硬连接 symlink "dodgson","carroll"or warn "Can't sysmlink Dodgson to carroll: $!"; shell 中使用 ln -s dodgson carroll 的结果是一样的。软连接 可以使用 unlink 删除任意类型的连接。 8、 创建和删除目录 使用 mkdir 函数: mkdir "fred",0755 or warn "Cannot make fred directory: $!"; 要删除一个空的目录,按照类似于 unlink 函数的方法使用 rmdir 函数: rmdir 在目录非空时失败。第一遍时,可以尝试使用 unlink 删除目录下的文件,其次再删除现在应当是空的目录。 my $temp_dir = "/tmp/scratch_$$"; #基于进程 ID mkdir $temp_dir, 0700 or die "cannot create $temp_dir: $!"; #将$temp_dir 作为所有的临时文件存放的地方 unlink glob "$temp_dir/* $temp_dir/."; #将$temp_dir 里面的文件删掉 rmdir $temp_dir; #将现在是空的目录删掉 9、修改权限 Perl 的 chomd 函数也能完成这种任务: chmod 0755, "fred","barney"; Unix 的 chomd 命令可以使用的符号权限(如+x 或 go=u-w)对 chomd 函数是无效的 File::chmod 模块可以 10、改变所有者 my $user = 1004; my $group = 100; chown $user, $group, glob "*.o"; 11、改变时间戳 my $now = time; my $ago = $now -24*60*60; #一天的秒数 utime $now, $ago, glob "*" #设成当前访问的,一天之前修改的