它将像数据库一样工作。
我想要的例子是:
输入: % perl youscript.pl Create_table mydb regtable REGION COUNTRY
输出:
mydb.txt(The contents of this file):
regtable
REGION|COUNTRY
和
输入: % perl youscript.pl Create_table mydb nametable SURNAME NAME
输出
mydb.txt(The contents of this file):
regtable
REGION|COUNTRY
nametable
SURNAME|NAME
应在每个条目中添加新条目。
ķ。 Rea:感谢您的帮助。
答案 0 :(得分:2)
您的示例实际上并不是数据库的工作方式。它只是一个可变长度记录的平面文件。如果您希望使查找更有效,则可以确保记录长度是固定的,或者保持单独的记录偏移索引。但这超出了回答你问题的范围。
脚本的运行语义似乎如下:
myscript ACTION_NAME FILENAME CONTENT [CONTENT [...]]
在脚本中,命令行上传递的字段将显示在@ARGV
数组中。
在下面的解决方案中,我假设您可能希望最终除了Create_table
之外还有其他操作,因此已经努力实现可扩展性。一个简单的假设是这些操作以某种方式对传递给@ARGV
的参数进行操作。至少Create_table
的情况如此。所以在@ARGV
内,我们会发现以下内容:
@ARGV = ($action, $filename, @fields);
首先,我们设置一个可以处理各种操作的调度表:
my %actions = (Create_table => sub {...}, ...);
然后我们需要转移行动:
my $action = shift @ARGV;
接下来我们需要应用调度:
if (exists $actions{$action}) {
$actions{$action}->(@ARGV);
}
else {
die "Unknown action: $action. Choose one of:\n\t",
join("\n\t", keys %actions),
"\n";
}
使用这种方法,我们只需将@ARGV
中的其余元素传递给与Create_table
操作相关联的匿名子元素,如果找不到匹配的操作,则会死亡。
现在我们要看的是在我们的行动的子程序中需要发生什么。我们传入的元素来自@ARGV
,将是:
($filename, $tablename, @content)
所以我们抓住这些论点:
my ($fname, $tname, @content) = @_;
然后我们需要以追加模式打开输出文件。使用'>>'
标识指定附加模式:
open my $out_fh, '>>', $fname
or die "Error opening $fname for append: $!\n";
最后一点是一些错误处理:如果文件无法打开,我们已经达到一个异常状态,在脚本的这一点上无法轻易恢复,所以我们抛出一个异常(die)并退出发送给STDERR的相应消息。
接下来,我们将一些文本附加到输出文件中。首先,我们附加表格名称,然后通过加入每个"单词"来打印@ARGV
(此时为@content
)的剩余项目。与' | '
一起使用:
print $out_fh "$tname\n", join(' | ', @content), "\n";
最后,我们明确关闭文件句柄,以便检测错误:
close $out_fh or die "Error writing to $fname: $!\n";
您现在可能已经注意到$!
几次了。在Perl中,如果系统调用(例如open
,close
和许多其他)失败,则特殊变量$!
将在字符串上下文中包含错误消息,因此将其附加到我们的错误输出将为调用者提供一些诊断信息。
总而言之,我们得到了这个:
#!/usr/bin/env perl
use strict;
use warnings;
my %actions = (
Create_table => sub {
my ($fname, $tname, @content) = @_;
open my $out_fh, '>>', $fname
or die "Could not complete action Create_table - Failed to open $fname for append: $!\n";
print $out_fh "$tname\n", join(' | ', @content), "\n";
close $out_fh or die "Error writing to $fname: $!\n";
},
);
my $action = shift @ARGV;
if (exists $actions{$action}) {
$actions{$action}->(@ARGV);
}
else {
die "Unknown action: $action\n";
}
通过在ACTION_NAME => sub {...},
哈希中填充更多%actions
元素,可以轻松添加其他操作处理。
如果您的命令行处理需要更详细,请参阅Perl附带的Getopt::Long
。
有关描述此示例代码中使用的构造的其他文档,请参阅:
perldoc perlintro
:Perl的简要介绍。perldoc perlopentut
,perldoc -f open
,perldoc -f close
:文件处理。perldoc perlvar
:$!
和@ARGV
的解释。perldoc -f join
perldoc -f die
:错误处理。perldoc perldata
:哈希的解释。perldoc perlreftut
:引用说明(包括子参数)perldoc perlsyn
:if(){}
语法的解释。perldoc perlsub
:子程序,参数传递和匿名潜艇的解释。Perl的文档在命令行中可用:
perldoc [-f] DOCUMENT_NAME
其中-f
用于指定单个函数或子例程,而不是更广泛的文档。
如果您是Perl的新手,请从perldoc perlintro
开始,然后从那里构建。