用正则表达式替换Perl

用正则表达式替换Perl,perl,substitution,Perl,Substitution,当我在Perl one liner上运行此命令时,它会选择正则表达式- 所以这不坏 more tagcommands | perl -nle 'print /(\d{8}_\d{9})/' | sort 12012011_000005769 12012011_000005772 12162011_000005792 12162011_000005792 但是,当我在下面的命令调用上运行此脚本时,它不会拾取 正则表达式 您的open调用可能会失败(您应该始终检查open的结果,以确保在程序的

当我在Perl one liner上运行此命令时,它会选择正则表达式- 所以这不坏

more tagcommands | perl -nle 'print /(\d{8}_\d{9})/' | sort 

12012011_000005769
12012011_000005772
12162011_000005792
12162011_000005792
但是,当我在下面的命令调用上运行此脚本时,它不会拾取 正则表达式


您的
open
调用可能会失败(您应该始终检查
open
的结果,以确保在程序的其余部分依赖它的情况下成功),但我认为您的问题在于,通过从
more
命令打开管道而不是简单地打开文件本身,从而使事情变得复杂。将open改为simply

open FILE, "/home/shortcasper/work/tagcommands" or die $!;

事情应该有所改善。

你应该研究一下你的一行代码,看看它是如何工作的。首先检查
perl-h
,了解使用的开关:

-l[octal]         enable line ending processing, specifies line terminator
-n                assume "while (<>) { ... }" loop around program
实际上是这样的:

$\ = "\n";
while (<>) {
    chomp;
    print /(\d{8}_\d{9})/;
}
您会注意到,它只需等待10秒钟,然后立即打印所有内容。这是因为perl在默认情况下打印到标准输出缓冲区(在shell中!),并且该缓冲区在满或刷新(perl执行结束时)之前不会打印。所以,这是一个感知问题。一切都正常运转,只是你看不到而已

如果您绝对希望在脚本中有一个sleep语句,您可能需要,例如
STDOUT->autoflush(1)

然而,你为什么要这样做?这样你就有时间看数字了吗?如果是这样,请将
more
语句放在一行代码的末尾

perl ...... | more
这将把输出导入
more
命令,这样您就可以按照自己的速度阅读它。现在,对于您的一行:

perl -nle 'print /(\d{8}_\d{9})/'
也要始终使用
-w
,除非您特别希望避免收到警告(基本上您永远不应该收到警告)

你的一行将只打印第一个匹配。如果要在新行上打印所有匹配项:

perl -wnle 'print for /(\d{8}_\d{9})/g'
如果要打印所有匹配项,但将来自同一行的匹配项保留在同一行上:

perl -wnle 'print "@a" if @a = /(\d{8}_\d{9})/g'

好吧,那就够了

你说的“不加正则表达式”是什么意思?您的代码将
12162011\u000005792d.binaryBlob.gz
更改为
12012011\u000005777d.binaryBlob.gz
,据我所知,这就是您打算执行的操作。此正则表达式的第一部分(\d{8}\ud{9})表示日期,第二部分表示唯一的会话id。在任何特定的一天,都可能有许多会话运行此作业。当我在java程序上运行这个perl one liner时,它会选择四个日期/会话对。当我使用perl one liner中使用的相同正则表达式运行perl脚本时,它不会对脚本中的四个日期/会话对进行任何更改。这就是我所说的perl脚本不拾取正则表达式的意思。没有人知道你说的“pick up”是什么意思……最终我要做的是将日期/会话对从java调用中切换出来——全部四个,而不仅仅是一个。它确实匹配并更改了所有四个。(
12012011_u000005777
12012011_000005777
12012011_000005777
12162011_000005792
)并分别更改为
12012011_000005777
。应该使用a)open的三参数版本和b)使用词汇文件句柄<代码>打开我的$filehandle,'我同意,但我正在展示问题的解决方案,而不是传播最佳实践。我认为解决方案不仅应该解决问题,还应该展示更好的方法。非常好的解释@TLP+1.
use strict; 
my $switch="12012011_000005777";
open (FILE, "more /home/shortcasper/work/tagcommands|");
my @array_old = (<FILE>) ;
my @array_new = @array_old ;
foreach my $line(@array_new) {
        $line =~ s/\d{8}_\d{9}/$switch/g;
        print $line;
        sleep 1;
}
perl -we 'for (1 .. 10) { print "line $_\n"; sleep 1; }'
perl ...... | more
perl -wnle 'print for /(\d{8}_\d{9})/g'
perl -wnle 'print "@a" if @a = /(\d{8}_\d{9})/g'