我有一个程序,我试图用管道(|)锚定行的开头。但是,当我执行它时,它会减少或删除我文件中的行。正如您将看到的,我并不是想要替换任何东西,只需要放置在某些行的开头。这是程序:
$DESCRIPTION = qr/^[0-9]+\.[0-9]+ +.*? {2,}[0-9]+.*? {2,}[0-9]+.*? {2,}[0-9]+.*? {2,}[0-9]+.*?$/;
$PRICELINE = qr/^[0-9]+.*? {2,}[0-9]+.*?$/;
$PRICELINE2 = qr/^.*? {2,}[0-9]+\.[0-9]+ {2,}[0-9]+\$/;
$CODE = qr/^\w{9}$/;
$date = qr/^AS OF.*?$/;
$accountnumber = qr/^ACCOUNT NUMBER.*?$/;
$name = qr/^CEOTID.*?$/;
while (<>) {
if (s/($DESCRIPTION)/\|$1/gi) {print STDOUT "1\n"; next LINE;};
if (s/($PRICELINE)/\|$1/gi) {print STDOUT "2\n"; next LINE;};
if (s/($PRICELINE2)/\|$1/gi) {print STDOUT "3\n"; next LINE;};
if (s/($CUSIP)/\|$1/gi) {print STDOUT "4\n"; next LINE;};
if (s/($date)/\|$1/g) {print STDOUT "5\n"; next LINE;};
if (s/($accountnumber)/\|$1/gi) {print STDOUT "6\n"; next LINE;};
if (s/($name)/\|$1/gi) {print STDOUT "7\n"; next LINE;};
print;
}
print "\n\ndone"
我试图一次消除一个变量,看看哪一个导致了故障,但仍然没有运气。我也只是使用了while语句,但它很慢并且仍然删除了我文件的第一行。
任何帮助都会很棒。
答案 0 :(得分:4)
编辑:请注意,您有一个未声明的变量$CUSIP
,您似乎与$CODE
混淆了。如果未启用strict
和warnings
,则此错误将是静默且致命的,但几乎不谨慎,因为它会在您的输入中插入管道符号。
我会猜测并说这是因为您尝试使用未定义的标签:LINE
。此标签以下列方式使用:
LINE: while (<>) {
... next LINE;
}
但你可以轻松地跳过它,然后只说next
,它将引用最里面的循环。但是,当你没有标签时,我的测试中似乎发生的事情就是它会以错误退出循环
Label not found for "next LINE" at ...
即使warnings
关闭,也会显示此错误。它永远不应该是。您编写的任何脚本的前两行应为:
use strict;
use warnings;
因为它会让你的生活更轻松。
你也应该知道你可以使用先行断言来解决你想要做的事情:
if (s/(?=$DESCRIPTION)/|/i) { ... }
你应该意识到这一点:
print STDOUT "1\n";
如果您通过-p
和-i
开关使用就地编辑,..仍然会打印到文件中。如果您需要某种反馈,可以打印到STDERR:
print STDERR "1\n";
warn "1\n"; # same thing
此外,您根本不必使用s///
运算符,只需检查该行,然后使用字符串插值添加管道符号:
if (/$DESCRIPTION/) { $_ = "|$_" }
此外,您根本不必使用next
:您可以使用普通的旧式逻辑:
if (/$DESCRIPTION/) { ... }
elsif (/$PRICELINE/) { ... }
所以你有它。请开始使用strict
和warnings
。
答案 1 :(得分:1)
LINE: while (<>) {
if (s/($DESCRIPTION)/\|$1/gi) {print STDOUT "1\n"; next LINE;};
...
print;
}
当执行next LINE
语句时,执行会返回到循环的顶部。你的最终print
语句永远不会被执行,似乎某些行被“删除”。
Perl提供while(EXPR) { BLOCK } continue { BLOCK }
语法,以便您可以在迭代结束时执行一些任意代码。您可以将print
语句放在continue
块中:
LINE: while (<>) {
if (s/($DESCRIPTION)/\|$1/gi) {print STDOUT "1\n"; next LINE;};
if (s/($PRICELINE)/\|$1/gi) {print STDOUT "2\n"; next LINE;};
if (s/($PRICELINE2)/\|$1/gi) {print STDOUT "3\n"; next LINE;};
if (s/($CUSIP)/\|$1/gi) {print STDOUT "4\n"; next LINE;};
if (s/($date)/\|$1/g) {print STDOUT "5\n"; next LINE;};
if (s/($accountnumber)/\|$1/gi) {print STDOUT "6\n"; next LINE;};
if (s/($name)/\|$1/gi) {print STDOUT "7\n"; next LINE;};
} continue {
print;
}
现在,即使执行了print
个子句之一,您的if
语句也会被执行。