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

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 perlShebang 行,告诉系统使用 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_caseparse_input()
常量UPPER_CASEMAX_RETRY
包名CamelCaseMyApp::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 检查你的脚本语法

扩展阅读