强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Perl 完全指南 / 第 3 章:第一个 Perl 程序

第 3 章:第一个 Perl 程序

“千里之行,始于足下” — 老子

本章将带你编写第一个 Perl 程序,理解脚本结构、运行方式以及 strictwarnings 的重要性。


3.1 Hello, World!

创建文件 hello.pl

#!/usr/bin/env perl
use strict;
use warnings;

print "Hello, World!\n";

运行:

perl hello.pl

输出:

Hello, World!

代码解析

部分 说明
#!/usr/bin/env perl Shebang 行,告诉系统使用 Perl 解释器
use strict; 启用严格模式(强烈推荐)
use warnings; 启用警告(强烈推荐)
print "Hello, World!\n"; 打印字符串,\n 是换行符

3.2 Shebang 行详解

Shebang 行是脚本文件的第一行,告诉操作系统用什么解释器来运行脚本。

#!/usr/bin/env perl          # 推荐:可移植性最好
#!/usr/bin/perl               # 直接指定路径(不推荐)
#!/usr/bin/perl -w             # 带 -w 参数启用警告

为什么推荐 #!/usr/bin/env perl

写法 优点 缺点
#!/usr/bin/env perl 自动找到 PATH 中的 perl 极少数系统不支持 env
#!/usr/bin/perl 简单直接 路径可能不对
#!/usr/local/bin/perl 明确 不可移植

让脚本可执行

chmod +x hello.pl
./hello.pl

3.3 语句与分号

Perl 中每条语句以分号 ; 结尾:

my $name = "Perl";      # 赋值语句
print "Hello, $name\n"; # 打印语句

代码块用花括号 {} 包裹,块内最后一条语句不需要分号:

if ($age >= 18) {
    print "成年人\n";    # 块内最后一条不需要分号
}

3.4 use strict — 严格模式

strict 是 Perl 的编译指令,强制执行三个约束:

strict 的三个限制

限制 说明 示例
strict 'vars' 变量必须先声明 my $x; $x = 1;
strict 'refs' 禁止字符串作为引用 不能 &{"func"}
strict 'subs' 裸字必须是已知子程序 print hello 会报错

不使用 strict 的问题

# 不使用 strict(危险!)
$name = "Perl";          # 拼写错误变成新变量
print $naem, "\n";       # typo,打印空值(无警告)

使用 strict 的安全

# 使用 strict(推荐!)
use strict;
my $name = "Perl";       # 必须用 my 声明
print $naem, "\n";       # 编译报错:Global symbol "$naem" requires explicit package name

3.5 use warnings — 警告模式

warnings 会在运行时对可疑代码发出警告:

use warnings;

my $x;
print $x;                # 警告:Use of uninitialized value
my $y = "abc" + 1;      # 警告:Argument "abc" isn't numeric

warnings 的常见警告

警告 原因
Use of uninitialized value 使用未初始化的变量
Name "main::x" used only once 变量只使用了一次(可能是 typo)
Argument "abc" isn't numeric 非数字参与数值运算
Possible unintended interpolation 字符串中可能有意外的变量插值
print() on closed filehandle 向已关闭的文件句柄写入

-w 命令行参数 vs use warnings

# 命令行启用(全局,包括所有模块)
perl -w script.pl

# 脚本内启用(推荐,仅限当前文件)
# 在脚本顶部使用 use warnings;

3.6 注释

Perl 使用 # 开始单行注释。没有多行注释语法

# 这是单行注释

my $x = 1;  # 行尾注释

# 多行注释需要每行都加 #
# 第一行
# 第二行
# 第三行

# 也可以用 POD 格式实现"多行注释"(不推荐)
=begin comment
这是多行注释
Perl 解释器会忽略 POD
=end comment
=cut

3.7 代码风格基础

缩进

推荐使用 4 个空格缩进(社区惯例):

#!/usr/bin/env perl
use strict;
use warnings;

sub greet {
    my ($name) = @_;
    if (defined $name) {
        print "Hello, $name!\n";
    } else {
        print "Hello, stranger!\n";
    }
}

greet("Perl");

命名规范

类型 风格 示例
标量变量 snake_case $user_name
数组 snake_case @file_list
哈希 snake_case %config_data
子程序 snake_case parse_input()
常量 UPPER_CASE MAX_RETRY
包名 CamelCase MyApp::Utils

3.8 运行 Perl 脚本的多种方式

方式 1:直接运行(最常见)

perl script.pl

方式 2:可执行脚本

chmod +x script.pl
./script.pl

方式 3:命令行 one-liner

perl -e 'print "Hello\n"'

方式 4:从 STDIN 读取

echo 'print "Hello\n"' | perl

方式 5:管道处理

cat data.txt | perl -ne 'print if /pattern/'

常用命令行参数

参数 说明 示例
-e 执行一行代码 perl -e 'print 1'
-n 逐行读取(隐式循环) perl -ne 'print if /foo/'
-p 逐行读取并打印 perl -pe 's/foo/bar/g'
-i 原地编辑文件 perl -i -pe 's/foo/bar/g' file.txt
-l 自动添加换行 perl -lne 'print'
-c 检查语法(不运行) perl -c script.pl
-d 启动调试器 perl -d script.pl
-w 启用警告 perl -w script.pl
-M 加载模块 perl -MJSON::XS -e '...'

3.9 代码检查与调试

语法检查

# 只检查语法,不运行
perl -c script.pl

输出示例:

script.pl syntax OK

使用 Perl::Tidy 格式化代码

cpanm Perl::Tidy
perltidy script.pl

使用 Perl::Critic 检查代码质量

cpanm Perl::Critic
perlcritic script.pl
perlcritic --severity 3 script.pl    # 只显示严重问题

内置调试器

perl -d script.pl

调试器常用命令:

命令 说明
n 执行下一行(不进入子程序)
s 执行下一行(进入子程序)
c 继续运行到断点
b <行号> 设置断点
p <表达式> 打印表达式值
x <变量> 详细打印变量内容
q 退出调试器
h 帮助

3.10 第一个实用脚本

一个简单但实用的脚本——统计文件中的单词频率:

#!/usr/bin/env perl
use strict;
use warnings;

# 检查命令行参数
die "用法: $0 <文件名>\n" unless @ARGV == 1;

my $filename = $ARGV[0];
die "文件 '$filename' 不存在\n" unless -f $filename;

# 统计单词频率
my %word_count;

open my $fh, '<', $filename or die "无法打开文件: $!\n";
while (my $line = <$fh>) {
    chomp $line;
    # 移除标点,转小写
    $line =~ s/[[:punct:]]//g;
    my @words = split /\s+/, lc($line);
    for my $word (@words) {
        next unless $word;       # 跳过空字符串
        $word_count{$word}++;
    }
}
close $fh;

# 按频率排序输出
print "文件: $filename\n";
print "=" x 40, "\n";

my $rank = 0;
for my $word (sort { $word_count{$b} <=> $word_count{$a} } keys %word_count) {
    $rank++;
    printf "%3d. %-20s %d 次\n", $rank, $word, $word_count{$word};
    last if $rank >= 20;        # 只显示前 20 个
}

运行:

perl word_freq.pl somefile.txt

3.11 Perl one-liners

Perl 最强大的特性之一是 one-liner(一行命令):

# 打印包含 "error" 的行
perl -ne 'print if /error/' logfile.txt

# 替换文件中的文本
perl -i -pe 's/old/new/g' file.txt

# 打印第 3-7 行
perl -ne 'print if 3..7' file.txt

# 统计行数
perl -lne 'END { print $. }' file.txt

# 去除重复行
perl -ne 'print unless $seen{$_}++' file.txt

# 格式化 CSV
perl -F, -lane 'print join "\t", @F' data.csv

# 反转每行
perl -lne 'print scalar reverse' file.txt

one-liner 参数说明

参数 说明
-n 为每一行执行代码(不自动打印)
-p 为每一行执行代码(自动打印)
-i 原地编辑(就地修改文件)
-e 指定代码
-l 自动添加换行符
-a 自动分割(类似 awk)
-F 指定分割模式

本章小结

要点 内容
Shebang #!/usr/bin/env perl 确保可移植性
strict 必须启用,强制变量声明,避免 typo
warnings 必须启用,运行时警告可疑代码
分号 每条语句以 ; 结尾
注释 使用 #,没有多行注释
运行方式 perl script.pl、可执行脚本、one-liner
代码检查 perl -c(语法)、perlcritic(质量)

练习

  1. 编写一个脚本,打印你的名字、年龄和爱好
  2. 故意去掉 use strict,使用未声明的变量,观察行为
  3. 编写一个 one-liner,统计 /etc/passwd 中有多少行
  4. 编写一个脚本,读取一个文件并打印其行数
  5. 使用 perl -c 检查你的脚本语法

扩展阅读