0

我正在编写一个创建 procmailrc 文本文件的 perl 程序。

输出 procmail 要求如下所示:(部分 IP 地址由“|”分隔)

\(\[54\.245\.|\(\[54\.252\.|\(\[60\.177\.|

这是我的 perl 脚本:

open (DEAD, "$dead");
@dead = <DEAD>;
foreach $line (@dead) { chomp $line; $line =~s /\./\\./g;
print FILE "\\(\\[$line\|\n"; }
close (DEAD);

这是我得到的输出:

|(\[54\.245\.
|(\[54\.252\.
|(\[60\.177\.

为什么 chomp 不删除换行符?更奇怪的是,为什么是'|' 出现在每行的前面,而不是最后?

如果我将 $line 替换为一个单词, (print FILE "\(\[test\|"; }) 输出看起来就像我期望的那样:

\(\[test|\(\[test|\(\[test|\(\[test|

我在这里想念什么?

所以我找到了一个不使用 chomp 的解决方法:答案在这里:https ://www.perlmonks.org/?node_id=504626

我的新代码:

open (DEAD, "$dead");
@dead = <DEAD>;
foreach $line (@junk) { 
$line =~ s/\r[\n]*//gm; $line =~ s/\./\\./g;  $line =~ s/\:/\\:/g;
print FILE "\\(\\[$line \|"; }
close (DEAD);

感谢那些给我一些提示的人。

4

1 回答 1

2

chomp删除 的值,该值设置为默认$/生成的字符串。"\n"

但是,对于输入,您有

@dead = (
   "54.245\.\r\n",
   "54.252\.\r\n",
   "60.177\.\r\n",
);

这个简单的修复:

open(my $dead_fh, '<', $dead_qfn)
   or die("Can't open \"$dead_qfn: $!\n");

while (my $line = <$dead_fh>) {
   $line =~ s/\s+\z//;
   $line =~ s/\./\\./g
   print($out_fh "\\(\\[$line\|");
}

print($out_fh "\n");

(另一种方法是将:crlf图层添加到您的输入句柄。)

使用quotemeta更有意义

open(my $dead_fh, '<', $dead_qfn)
   or die("Can't open \"$dead_qfn: $!\n");

while (my $line = <$dead_fh>) {
   $line =~ s/\s+\z//;
   print($out_fh quotemeta("([$line|"));
}

print($out_fh "\n");
于 2018-07-07T22:21:32.370 回答