table {
border-collapse: collapse;
width: 100%;
margin-bottom: 1rem;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
pre {
background-color: #f8f8f8;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
}
26、修改程序以包含所有文件,而不仅仅是不以点开头的文件。
若要修改程序以包含所有文件,而不跳过以点开头的文件,可移除代码中跳过点文件的逻辑。
例如在以下代码里:
opendir my $somedir, $dirname or die "Cannot open $dirname: $!";
while (my $name = readdir $somedir) {
next if $name =~ /^./; # skip over dot files
$name = "$dirname/$name"; # patch up the path
next unless -f $name and -r $name; # only readable files
...
}
可去掉
这一行,修改后的代码如下:
next if $name =~ /^./;
opendir my $somedir, $dirname or die "Cannot open $dirname: $!";
while (my $name = readdir $somedir) {
$name = "$dirname/$name"; # patch up the path
next unless -f $name and -r $name; # only readable files
...
}
这样程序就会包含所有文件,而不跳过以点开头的文件。
27、编写一个程序,其功能类似于
rm
命令,用于删除命令行中指定的任何文件。(你无需处理
rm
的任何选项)
rm
rm
可以使用Perl语言编写如下程序:
#!/usr/bin/perl
use strict;
use warnings;
# 获取命令行参数中的文件名列表
my @files = @ARGV;
# 使用unlink操作符删除文件
unlink @files;
将上述代码保存为一个
文件,例如
.pl
,然后在命令行中运行
rm_like.pl
即可删除指定的文件。
perl rm_like.pl file1 file2 ...
28、编写一个程序,其功能类似于
mv
命令,将第一个命令行参数重命名为第二个命令行参数。(你不需要处理
mv
的任何选项或额外参数。)请记住要考虑目标可能是一个目录的情况;如果是目录,则在新目录中使用相同的原始基本名称。
mv
mv
use File::Basename;
use File::Spec;
my ($source, $dest) = @ARGV;
if (-d $dest) {
my $basename = basename $source;
$dest = File::Spec->catfile($dest, $basename);
}
rename $source, $dest or die "Can't rename '$source' to '$dest': $!
";
29、编写一个程序,读入一个数字列表并对其进行数值排序,将排序后的列表以右对齐的列形式输出。用以下示例数据进行测试:17 1000 04 1.50 3.14159 –10 1.5 4 2001 90210 666
以下是实现该功能的 Perl 代码:
#!/usr/bin/perl
use strict;
use warnings;
# 读取输入的数字列表
my @numbers;
while (<>) {
push @numbers, split;
}
# 定义数值排序子程序
sub by_number {
$a <=> $b
}
# 对数字列表进行数值排序
my @sorted_numbers = sort by_number @numbers;
# 输出排序后的数字,以右对齐的列形式
foreach my $number (@sorted_numbers) {
printf "%20g
", $number;
}
将上述代码保存为一个
文件,例如
.pl
,然后在终端中运行以下命令并输入示例数据:
sort_numbers.pl
perl sort_numbers.pl
17 1000 04 1.50 3.14159 -10 1.5 4 2001 90210 666
按
(在 Windows 上按
Ctrl + D
)结束输入,程序将输出排序后的数字列表,以右对齐的列形式显示。
Ctrl + Z
30、编写一个程序,在给定的字符串中查找给定子字符串的每一次出现,并打印出子字符串所在的位置。例如,给定输入字符串 “This is a test.” 和子字符串 “is”,程序应报告位置 2 和 5。如果子字符串是 “a”,则应报告 8。如果子字符串是 “t”,程序应报告哪些位置?
程序应报告位置 0、10 和 13
31、使用
given
和智能匹配,编写一个程序,报告你在命令行中指定的数字的所有因数(除了 1 和该数字本身)。例如,对于数字 99,你的程序应该报告它能被 3、9、11 和 33 整除。如果该数字是质数(没有因数),则报告该数字是质数。如果命令行参数不是数字,报告错误并且不要尝试计算因数。尽管你可以使用
if
结构和普通匹配来完成这个任务,但只能使用智能匹配。
given
if
use 5.010;
say "Checking the number <$ARGV[0]>";
given( $ARGV[0] ) {
when( ! /Ad+/ ) {
say "Not a number!"
}
my @divisors = divisors( $_ );
my @empty;
when( @divisors ~~ @empty ) {
say "Number is prime"
}
default {
say "$_ is divisible by @divisors"
}
}
sub divisors {
my $number = shift;
my @divisors = ();
foreach my $divisor ( 2 .. $number/2 ) {
push @divisors, $divisor unless $number % $divisor;
}
return @divisors;
}
32、编写一个程序,接收一个数字作为输入,报告该数字是奇数还是偶数、该数字是否为质数(除了 1 和它本身没有其他约数),以及该数字是否能被你喜欢的数字(假设你喜欢的数字为 42)整除。仅使用智能匹配。
use 5.010;
say "Checking the number <$ARGV[0]>";
my $favorite = 42;
given( $ARGV[0] ) {
when( ! /Ad+/ ) {
say "Not a number!"
}
my @divisors = divisors( $ARGV[0] );
when( @divisors ~~ 2 ) {
# 2 is in @divisors
say "$_ is even";
continue;
}
when( !( @divisors ~~ 2 ) ) {
# 2 isn't in @divisors
say "$_ is odd";
continue;
}
when( @divisors ~~ $favorite ) {
say "$_ is divisible by my favorite number";
continue;
}
when( $favorite ) {
# $_ ~~ $favorite
say "$_ is my favorite number";
continue;
}
my @empty;
when( @divisors ~~ @empty ) {
say "Number is prime"
}
default {
say "$_ is divisible by @divisors"
}
}
sub divisors {
my $number = shift;
my @divisors = ();
foreach my $divisor ( 2 .. ($number/2 + 1) ) {
push @divisors, $divisor unless $number % $divisor;
}
return @divisors;
}
33、编写一个程序,将当前工作目录更改为某个特定的(硬编码)目录,例如系统的根目录,然后执行
ls -l
命令以获取该目录的长格式目录列表。(如果你使用的是非 Unix 系统,请使用你自己系统的命令来获取详细的目录列表。)
ls -l
以下是实现该功能的代码:
chdir '/' or die "Can't chdir to root directory: $!";
exec 'ls', '-l' or die "Can't exec ls: $!";
第一行将当前工作目录更改为根目录,第二行使用多参数
函数执行
exec
命令并将结果发送到标准输出。
ls -l
34、修改之前的程序,将命令的输出发送到当前目录下名为 ls.out 的文件中。错误输出应发送到名为 ls.err 的文件中。(你无需特别处理这两个文件可能为空的情况)
可使用如下命令实现:
$ ls 1>ls.out 2>ls.err
该命令将标准输出重定向到
文件,将标准错误输出重定向到
ls.out
文件。
ls.err
35、编写一个程序,解析
date
命令的输出以确定当前是星期几。如果是工作日,则输出
get to work
;否则,输出
go play
。
date
命令的输出在周一以
Mon
开头。如果你使用的非Unix系统没有
date
命令,可以编写一个简单的伪程序,使其输出类似
date
命令的字符串。也可以使用以下两行代码:#!/usr/bin/perl print localtime( ). “
”;
date
get to work
go play
date
Mon
date
date
以下是一个满足需求的Perl程序示例:
#!/usr/bin/perl
use strict;
use warnings;
# 获取date命令的输出
my $date_output = `date`;
# 提取星期几
if ($date_output =~ /^(Mon|Tue|Wed|Thu|Fri)/) {
print "get to work
";
} else {
print "go play
";
}
如果你的系统没有
命令,可以使用提供的两行代码替换获取
date
输出的部分:
date
#!/usr/bin/perl
use strict;
use warnings;
# 获取类似date命令输出的字符串
my $date_output = localtime() . "
";
# 提取星期几
if ($date_output =~ /^(Mon|Tue|Wed|Thu|Fri)/) {
print "get to work
";
} else {
print "go play
";
}
36、编写一个仅适用于Unix系统的无限循环程序,该程序能捕获信号,并报告捕获到了哪个信号以及之前看到该信号的次数。如果捕获到INT信号则退出程序。若可以使用命令行的kill命令,可通过 $ kill -USR1 12345 发送信号;若不能使用命令行的kill命令,可编写另一个程序向它发送信号,也可使用Perl单行命令:$ perl -e ‘kill HUP => 12345’。
以下是符合要求的程序代码:
use 5.010;
sub my_hup_handler {
state $n;
say 'Caught HUP: ', ++$n
}
sub my_usr1_handler {
state $n;
say 'Caught USR1: ', ++$n
}
sub my_usr2_handler {
state $n;
say 'Caught USR2: ', ++$n
}
sub my_int_handler {
say 'Caught INT. Exiting.';
exit
}
say "I am $$";
foreach my $signal ( qw(int hup usr1 usr2) ) {
$SIG{ uc $signal } = "my_${signal}_handler";
}
while(1) {
sleep 1
};
要向该程序发送信号,可在另一个终端会话中运行以下命令:
$ kill -HUP <进程ID>
$ perl -e 'kill HUP => <进程ID>
$ perl -e 'kill USR2 => <进程ID>'
运行该程序后,输出会显示捕获到的信号及其计数,捕获到INT信号时程序将退出。
37、修改练习的答案,使用YYYY – MM – DD格式报告时间。使用带有localtime和切片的map将纪元时间转换为所需的日期字符串。注意localtime文档中关于它返回的年份和月份值的说明。你的报告应如下所示:fred.txt 2011 – 10 – 15 2011 – 09 – 28 barney.txt 2011 – 10 – 13 2011 – 08 – 11 betty.txt 2011 – 10 – 15 2010 – 07 – 24
foreach my $file ( glob( '*' ) ) {
my( $atime, $mtime ) = map {
my( $year, $month, $day ) = (localtime($_))[5,4,3];
$year += 1900;
$month += 1;
sprintf '%4d-%02d-%02d', $year, $month, $day;
} (stat $file)[8,9];
printf "%-20s %10s %10s
", $file, $atime, $mtime;
}
38、使用Perl语言输出“Hello, world!”,可以有哪些实现方式?
有以下几种实现方式:
使用
函数:
print
perl print "Hello, world!
";
若使用 Perl 5.10 或更高版本,可使用
函数:
say
perl use 5.010; say "Hello, world!";
从命令行运行,使用
开关:
-e
bash $ perl -e 'print "Hello, World
"'
从命令行运行,使用
开关自动添加换行符:
-l
bash $ perl -le 'print "Hello, World"'
39、编写一个Perl程序,从用户输入获取圆的半径,计算并输出该圆的周长
以下是实现该功能的 Perl 程序:
#!/usr/bin/perl
use strict;
use warnings;
print "请输入圆的半径: ";
chomp(my $radius = <STDIN>);
my $circumference = 2 * 3.14159 * $radius;
print "该圆的周长是: $circumference
";
将上述代码保存为一个
文件,例如
.pl
,然后在终端中运行
circle_perimeter.pl
,按照提示输入圆的半径,程序将计算并输出圆的周长。
perl circle_perimeter.pl
40、编写一个Perl程序,计算半径为12.5的圆的周长,并输出结果
#!/usr/bin/perl
use 5.010;
my $radius = 12.5;
my $circumference = 2 * 3.14159 * $radius;
say "半径为12.5的圆的周长是: $circumference";
41、编写一个Perl程序,提示用户输入圆的半径,然后计算并输出该圆的周长
以下是一个满足需求的Perl程序:
#!/usr/bin/perl
use strict;
use warnings;
print "请输入圆的半径: ";
my $radius = <STDIN>;
chomp($radius);
my $circumference = 2 * 3.14159 * $radius;
print "该圆的周长是: $circumference
";
该程序首先提示用户输入圆的半径,接着读取用户输入并去除换行符,然后使用公式
计算圆的周长,最后输出计算结果。
2 * π * 半径
42、编写一个Perl程序,提示用户输入圆的半径,检查半径是否为负数,如果是则将周长设为0,最后输出圆的周长
以下是实现该功能的Perl程序:
#!/usr/bin/perl
use strict;
use warnings;
print "请输入圆的半径: ";
my $radius = <STDIN>;
chomp($radius);
if ($radius < 0) {
$radius = 0;
}
my $circumference = 2 * 3.14159 * $radius;
print "圆的周长是: $circumference
";
该程序首先提示用户输入圆的半径,然后检查输入的半径是否为负数,如果是则将半径设为0,最后计算并输出圆的周长。
43、编写一个Perl程序,提示用户输入两个数字,计算它们的乘积并输出结果
以下是实现该功能的Perl程序代码:
print "请输入第一个数字: ";
chomp(my $num1 = <STDIN>);
print "请输入第二个数字: ";
chomp(my $num2 = <STDIN>);
my $product = $num1 * $num2;
print "这两个数字的乘积是: $product
";
将上述代码保存为一个
文件,例如
.pl
,然后在终端中运行
multiply.pl
即可。程序会依次提示你输入两个数字,输入完成后会计算并输出它们的乘积。
perl multiply.pl
44、编写一个Perl程序,提示用户输入一个字符串和一个数字,将字符串重复指定的次数并输出结果
以下是实现该功能的Perl程序:
#!/usr/bin/perl
use strict;
use warnings;
print "请输入一个字符串: ";
chomp(my $string = <STDIN>);
print "请输入一个数字: ";
chomp(my $number = <STDIN>);
my $result = $string x $number;
print "重复后的结果是: $result
";
将上述代码保存为一个
文件,例如
.pl
,然后在命令行中运行
repeat_string.pl
,按照提示输入字符串和数字,程序会将字符串重复指定的次数并输出结果。
perl repeat_string.pl
45、编写一个Perl程序,提示用户输入多行文本,然后将这些行反转并输出
以下是一个满足需求的Perl程序示例:
#!/usr/bin/perl
use warnings;
use strict;
print "请输入多行文本,输入空行结束输入:
";
my @lines;
while (<STDIN>) {
chomp;
last if $_ eq '';
push @lines, $_;
}
@lines = reverse @lines;
foreach my $line (@lines) {
print $line, "
";
}
将上述代码保存为一个
文件,如
.pl
,然后在终端中运行
reverse_lines.pl
,按照提示输入多行文本,输入空行结束输入,程序会将输入的行反转后输出。
perl reverse_lines.pl
46、有一个数组 @names = qw/ fred betty barney dino wilma pebbles bamm – bamm /,编写程序让用户输入 1 到 7 的数字,每行一个,按 Ctrl – D 结束输入,然后根据用户输入的数字输出对应的数组元素
以下是实现该功能的 Perl 代码:
@names = qw/ fred betty barney dino wilma pebbles bamm - bamm /;
while (<>) {
chomp;
if ($_ >= 1 && $_ <= 7) {
print $names[$_ - 1], "
";
} else {
print "输入的数字不在 1 到 7 的范围内,请重新输入。
";
}
}
这段代码首先定义了数组
,然后使用
@names
循环读取用户输入,每次读取一行并去除换行符。接着检查输入的数字是否在 1 到 7 的范围内,如果是,则输出数组中对应的元素;如果不是,则提示用户重新输入。按 Ctrl – D 结束输入。
while (<>)
47、编写程序,让用户输入一些行,按 Ctrl – D 结束输入,将输入的行排序后输出,要求实现输出在一行和输出在多行两种情况
以下是实现该功能的 Perl 代码:
#!/usr/bin/perl
use strict;
use warnings;
# 读取用户输入,直到按下 Ctrl-D
my @lines;
while (my $line = <STDIN>) {
chomp $line;
push @lines, $line;
}
# 对输入的行进行排序
my @sorted_lines = sort @lines;
# 输出在多行
print "多行输出:
";
foreach my $line (@sorted_lines) {
print $line, "
";
}
# 输出在一行
print "一行输出:";
print join(" ", @sorted_lines), "
";
上述代码首先读取用户输入的行,存储在数组中。接着对数组进行排序,然后分别以多行和一行的形式输出排序后的行。
48、编写一个子例程 total,用于计算传入参数的总和
以下是编写
子例程的代码:
total
sub total {
my $sum = 0;
foreach my $num (@_) {
$sum += $num;
}
return $sum;
}
这个子例程接收一个数字列表作为参数,通过遍历列表中的每个数字并将其累加到
变量中,最后返回总和。
$sum
49、编写程序,让用户输入一个字符串和一个数字,将字符串重复该数字次数后输出,要求字符串出现在不同行
以下是使用 Python 实现的代码:
string = input("请输入一个字符串:")
number = int(input("请输入一个数字:"))
for i in range(number):
print(string)
上述代码首先通过
函数获取用户输入的字符串和数字,将数字转换为整数类型。然后使用
input
循环,循环次数为用户输入的数字,在每次循环中打印字符串,从而实现字符串重复指定次数并分行输出。
for