Perl编程实践:文件操作与程序实现

内容分享2天前发布
0 0 0

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;
}

24、编写一个程序,其功能类似于

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': $!
";

程序首先引入必要的模块,然后将命令行参数赋值给

$source


$dest

。如果

$dest

是一个目录,就从

$source

中提取基本名称并追加到

$dest

目录后。最后使用

rename

函数进行重命名操作,如果失败则输出错误信息。

25、编写一个程序,允许在其他参数前使用可选的 -s 开关,以表明你想创建软链接而不是硬链接。若目标是目录,则将源文件的基本名称添加到目标目录路径后,并且在创建链接失败时输出错误信息。


my $symlink = $ARGV[0] eq '-s';
shift @ARGV if $symlink;
my($source, $dest) = @ARGV;
if (-d $dest) {
    use File::Basename;
    my $basename = basename $source;
    use File::Spec;
    $dest = File::Spec->catfile($dest, $basename);
}
if ($symlink) {
    symlink $source, $dest or die "Can't make soft link from '$source' to '$dest': $!
";
} else {
    link $source, $dest or die "Can't make hard link from '$source' to '$dest': $!
";
}


代码解释:


代码开头检查第一个命令行参数是否为

-s

,如果是则将

$symlink

设为真,并移除

-s

参数。接着获取源文件和目标文件路径,如果目标是目录,则将源文件的基本名称添加到目标目录路径后。最后根据

$symlink

的值,选择创建软链接或硬链接,并在创建失败时输出错误信息。

26、如果你的操作系统支持,编写一个程序来查找当前目录中的所有符号链接,并打印出它们的值(就像

ls -l

那样:名称 -> 值)。


foreach ( glob( '.* *' ) ) {
    my $dest = readlink $_;
    print "$_ -> $dest
" if defined $dest;
}

27、编写一个程序,读取一组数字,对其进行数值排序,并将结果以右对齐的列形式打印出来。用以下示例数据进行测试:17 1000 04 1.50 3.14159 -10 1.5 4 2001 90210 666

可以使用以下 Perl 代码实现该功能:


while (<>) {
    push @numbers, split;
}

my @sorted_numbers = sort { $a <=> $b } @numbers;

foreach (@sorted_numbers) {
    printf "%20g
", $_;
}

这段代码首先使用

while

循环读取输入的数字,将其存入

@numbers

数组。然后使用

sort

函数对数组中的数字进行数值排序。最后,使用

foreach

循环遍历排序后的数组,并使用

printf

函数以右对齐的列形式打印每个数字,格式为

%20g

28、编写一个程序,将以下哈希表的数据按姓氏进行不区分大小写的字母顺序排序。当姓氏相同时,再按名字(同样不区分大小写)排序。也就是说,输出中的第一个名字应该是 Fred 的,而最后一个应该是 Betty 的。所有姓氏相同的人应该分组在一起。不要修改数据。名字应该按照这里显示的大小写进行打印。哈希表为:my %last_name = ( ‘fred’ => ‘flintstone’, ‘Wilma’ => ‘Flintstone’, ‘Barney’ => ‘Rubble’, ‘betty’ => ‘rubble’, ‘Bamm – Bamm’ => ‘Rubble’, ‘PEBBLES’ => ‘FLINTSTONE’ );

以下是解决该问题的 Perl 代码:


my %last_name = ( 'fred' => 'flintstone', 'Wilma' => 'Flintstone', 'Barney' => 'Rubble', 'betty' => 'rubble', 'Bamm - Bamm' => 'Rubble', 'PEBBLES' => 'FLINTSTONE' );
my @sorted_names = sort { lc($last_name{$a}) cmp lc($last_name{$b}) or lc($a) cmp lc($b) } keys %last_name;
foreach my $name (@sorted_names) {
    print "$name $last_name{$name}
";
}

这段代码首先定义了哈希表

%last_name

,然后使用

sort

函数对哈希表的键进行排序。排序规则是先按姓氏的小写形式进行字母顺序排序,如果姓氏相同,则按名字的小写形式排序。最后,遍历排序后的名字列表并打印出名字和对应的姓氏。

29、编写一个程序,在给定的字符串中查找给定子字符串的所有出现位置,并打印出这些位置。例如,对于输入字符串 “This is a test.” 和子字符串 “is”,程序应报告位置 2 和 5。如果子字符串是 “a”,则应报告 8。那么,如果子字符串是 “t”,程序会报告哪些位置?

对于字符串

"This is a test."

和子字符串

"t"

,程序应报告位置

0


11


13

30、编写一个程序,切换到某个特定的(硬编码的)目录,例如系统的根目录,然后执行

ls -l

命令以获取该目录的长格式目录列表。(如果使用非 Unix 系统,请使用自己系统的命令来获取详细的目录列表)。

以下是实现该功能的 Perl 代码示例:


chdir '/' or die "Can't chdir to root directory: $!";
exec 'ls', '-l' or die "Can't exec ls: $!";

上述代码首先尝试切换到根目录,如果切换失败则输出错误信息。接着执行

ls -l

命令,如果执行失败也会输出错误信息。如果使用非 Unix 系统,需要将

ls -l

替换为对应系统获取详细目录列表的命令。

31、修改上一个程序,将命令的输出发送到当前目录下名为 ls.out 的文件中。错误输出应发送到名为 ls.err 的文件中。(你无需对这两个文件最终可能为空的情况做特殊处理。)

以下是能实现该功能的代码:


open STDOUT, '>', 'ls.out' or die "Can't write to ls.out: $!";
open STDERR, '>', 'ls.err' or die "Can't write to ls.err: $!";
chdir '/' or die "Can't chdir to root directory: $!";
exec 'ls', '-l' or die "Can't exec ls: $!";

代码的第一行和第二行在更改目录前,将标准输出(STDOUT)和标准错误(STDERR)重新定向到当前目录下的文件。目录更改后,执行目录列表命令,并将数据发送回原目录中打开的文件。

32、编写一个程序,解析日期以确定当前是星期几。如果是工作日,打印“get to work”;否则,打印“go play”。日期格式中周一以“Mon”开头。若所在系统没有日期命令,可编写一个简单的伪程序输出类似日期命令的字符串。例如有一个两行的程序:#!/usr/bin/perl print localtime( ). “
”;

以下是一个满足需求的Perl程序示例:


#!/usr/bin/perl

# 获取日期命令的输出
my $date_output = `date`; # 如果是非Unix系统,可使用 print localtime( ). "
"; 替换

# 提取星期信息
if ($date_output =~ /^(Mon|Tue|Wed|Thu|Fri)/) {
    print "get to work
";
} else {
    print "go play
";
}

该程序首先获取日期命令的输出,然后通过正则表达式匹配输出的开头是否为工作日(周一至周五)。如果是,则打印“get to work”;否则,打印“go play”。

33、运行 perldoc 命令。如果你找不到 perldoc,弄清楚该怎么做。

perldoc

通常随 Perl 安装包一起提供,可直接运行。若找不到它,可能需要在系统上安装另一个软件包,例如在 Ubuntu 系统中,需安装

perl-doc

包。

34、编写一个程序来计算并打印半径为12.5的圆的周长。


#!/usr/bin/perl
use warnings;
$pi = 3.141592654;
$radius = 12.5;
$circ = 2 * $pi * $radius;
print "The circumference of a circle of radius $radius is $circ.
";

35、编写程序计算半径为 12.5 的圆的周长

在 Perl 中可以这样编写程序来计算半径为 12.5 的圆的周长:


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

my $radius = 12.5;
my $circumference = 2 * 3.14159 * $radius;
print "半径为 12.5 的圆的周长是: $circumference
";

上述代码中,首先定义了圆的半径为 12.5,然后根据圆的周长公式

C = 2πr

计算周长,最后将结果输出。

36、编写程序,让用户输入圆的半径,然后计算并输出该圆的周长

以下是使用Python语言实现的代码:


import math
# 获取用户输入的半径
radius = float(input("请输入圆的半径:"))
# 计算圆的周长
circumference = 2 * math.pi * radius
# 输出圆的周长
print("该圆的周长是:", circumference)

在上述代码中,首先导入

math

模块,该模块提供了数学相关的函数和常量,其中

math.pi

表示圆周率π。然后使用

input()

函数获取用户输入的半径,并将其转换为浮点数类型。接着根据圆的周长公式

C = 2πr

计算圆的周长。最后使用

print()

函数输出计算得到的圆的周长。

37、编写程序,让用户输入圆的半径,若半径为负数,周长设为 0 并输出该圆的周长

以下是使用 Python 实现该功能的代码:


import math
# 提示用户输入半径
radius = float(input("请输入圆的半径: "))
# 判断半径是否为负数
if radius < 0:
    circumference = 0
else:
    # 计算周长
    circumference = 2 * math.pi * radius
# 输出周长
print("圆的周长是: ", circumference)

代码解释:


导入

math

模块

:用于获取圆周率

math.pi


获取用户输入

:使用

input()

函数提示用户输入圆的半径,并将其转换为浮点数。


判断半径是否为负数

:如果半径小于 0,则将周长设为 0;否则,使用公式

2 * math.pi * radius

计算周长。


输出结果

:使用

print()

函数输出圆的周长。

38、编写程序,让用户输入两个数字,计算它们的乘积并输出结果

以下是使用 Python 语言实现的示例代码:


num1 = float(input("请输入第一个数字:"))
num2 = float(input("请输入第二个数字:"))
result = num1 * num2
print(f"两数的乘积是:{result}")

这段代码首先使用

input

函数获取用户输入的两个数字,将其转换为浮点数类型,然后计算它们的乘积,最后使用

print

函数输出结果。

39、编写程序,让用户输入一个字符串和一个数字,将字符串重复指定次数并输出结果

以下是一个使用 Python 实现的示例代码:


string = input("请输入一个字符串:")
number = int(input("请输入一个数字:"))
result = string * number
print(result)

这段代码首先通过

input

函数获取用户输入的字符串和数字,将数字转换为整数类型,然后使用乘法运算符将字符串重复指定次数,最后输出结果。

40、编写程序,定义一个包含几个名字的数组,让用户输入 1 到 7 的数字,根据数字输出对应的名字

以下是一个 Perl 语言的示例代码来实现该功能:


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

# 定义包含名字的数组
my @names = ('Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank', 'Grace');

# 提示用户输入数字
print "请输入 1 到 7 的数字: ";
my $input = <STDIN>;
chomp($input);

# 检查输入是否在有效范围内
if ($input >= 1 && $input <= 7) {
    print $names[$input - 1]. "
";
} else {
    print "输入的数字不在 1 到 7 的范围内。
";
}

这段代码首先定义了一个包含 7 个名字的数组,然后提示用户输入 1 到 7 的数字,根据用户输入输出对应的名字,如果输入不在有效范围内则给出提示。

41、编写程序,让用户输入一些行,对这些行进行排序并输出排序后的结果

以下是一个简单的Python程序示例来实现该功能:


lines = []
while True:
    try:
        line = input()
        lines.append(line)
    except EOFError:
        break
lines.sort()
for line in lines:
    print(line)

这个程序会不断读取用户输入的行,直到遇到文件结束符(EOF),然后对这些行进行排序并逐行输出排序后的结果。在不同操作系统中,输入EOF的方式不同,在Windows中是按Ctrl + Z然后回车,在Unix/Linux/Mac OS中是按Ctrl + D。

42、编写代码实现:提示用户输入一些行,然后按 Ctrl – D(或 Ctrl – Z),将用户输入的行反转并输出

以下是使用 Perl 语言实现该功能的代码:


print "请输入一些行,完成后按 Ctrl - D(或 Ctrl - Z):
";
my @lines;
while (my $line = <STDIN>) {
    chomp $line;
    push @lines, $line;
}
my @reversed_lines = reverse @lines;
foreach my $line (@reversed_lines) {
    print $line, "
";
}

这段代码首先提示用户输入行,使用

while

循环读取用户输入的每一行并存储在数组

@lines

中。当用户按下 Ctrl – D(或 Ctrl – Z)时,循环结束。接着使用

reverse

函数反转数组中的元素,并使用

foreach

循环逐行输出反转后的内容。

43、编写代码实现:给定数组 @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 /;
print "请输入 1 到 7 的数字,每行一个,按 Ctrl - D 结束输入:
";
while(<STDIN>) {
    chomp;
    if ($_ >= 1 && $_ <= 7) {
        print $names[$_ - 1]. "
";
    } else {
        print "输入的数字不在 1 到 7 的范围内,请重新输入。
";
    }
}

代码解释:

定义数组

@names

存储给定的元素。

提示用户输入 1 到 7 的数字。

使用

while(<STDIN>)

循环读取用户输入,直到用户按 Ctrl – D 结束输入。

chomp

函数用于去除输入行末尾的换行符。

检查输入的数字是否在 1 到 7 的范围内,如果是,则输出数组中对应位置的元素(数组索引从 0 开始,所以要减 1);如果不是,则提示用户重新输入。

44、编写代码实现:对用户输入的行进行排序并输出,分别实现输出在一行和输出在多行的情况

以下是使用 Python 语言实现该功能的代码示例:


# 获取用户输入的行
lines = []
while True:
    line = input()
    if not line:
        break
    lines.append(line)

# 对输入的行进行排序
sorted_lines = sorted(lines)

# 输出在一行
print(' '.join(sorted_lines))

# 输出在多行
for line in sorted_lines:
    print(line)

在这个代码中,首先通过一个循环获取用户输入的行,直到用户输入空行为止。然后使用

sorted()

函数对输入的行进行排序。最后分别使用

join()

方法将排序后的行用空格连接成一行输出,以及通过循环逐行输出排序后的行。

45、编写一个名为 total 的子例程,用于计算传入参数的总和

在 Perl 中可以这样实现:


sub total {
    my $sum = 0;
    foreach my $num (@_) {
        $sum += $num;
    }
    return $sum;
}

以上代码定义了

total

子例程,它会遍历传入的所有参数并累加,最后返回总和。

46、编写一个子程序来计算传入参数的总和,考虑传入空参数列表时的返回值情况

以下是一个 Perl 语言的子程序示例,用于计算传入参数的总和,并处理传入空参数列表的情况:


sub sum_numbers {
    my $total = 0;
    foreach my $num (@_) {
        $total += $num;
    }
    return $total;
}

在这个子程序中,使用

foreach

循环遍历传入的所有参数,将每个参数累加到

$total

变量中。如果传入的参数列表为空,循环不会执行,

$total

保持初始值 0,最后返回 0。

你可以通过以下方式调用这个子程序:


my $result1 = sum_numbers(1, 2, 3);
my $result2 = sum_numbers();
print "Result 1: $result1
";
print "Result 2: $result2
";

上述代码中,

$result1

将得到 6,

$result2

将得到 0。

47、编写一个子程序来计算传入参数的平均值,再编写一个子程序找出传入参数中大于平均值的元素

以下是实现这两个功能的 Perl 代码示例:


# 计算平均值的子程序
sub calculate_average {
    my $sum = 0;
    my $count = scalar @_;
    foreach my $num (@_) {
        $sum += $num;
    }
    return $count > 0 ? $sum / $count : 0;
}

# 找出大于平均值元素的子程序
sub find_greater_than_average {
    my $average = calculate_average(@_);
    my @result;
    foreach my $num (@_) {
        if ($num > $average) {
            push @result, $num;
        }
    }
    return @result;
}

# 测试代码
my @numbers = (1, 2, 3, 4, 5);
my $avg = calculate_average(@numbers);
print "平均值: $avg
";
my @greater_than_avg = find_greater_than_average(@numbers);
print "大于平均值的元素: @greater_than_avg
";

在上述代码中,

calculate_average

子程序用于计算传入参数的平均值,

find_greater_than_average

子程序用于找出传入参数中大于平均值的元素。最后给出了测试代码,方便验证这两个子程序的功能。

© 版权声明

相关文章

暂无评论

none
暂无评论...