我有一个文件eg.txt
,其中包含以下内容:
....text...
....text...
COMP1 = ../../path1/path2/path3
COMP2 = ../../path4/path5/path6
等等,对于大量的应用程序名称(“COMP”)。对于用户指定的应用程序,我需要获取路径 - 包括第二个斜杠后的内容。
这是我一直在尝试的代码:
use strict;
use warnings;
my $line = "";
my $app = "";
print "Enter the app";
$app = <STDIN>;
print $app;
open my $fh, '<', "eg.txt" or die "Cannot open $!";
while (<$fh>) {
$line = <$fh>;
if ( $line && $line =~ /($app)( = )(..\/)(..)(.*)/ ) {
print $5;
}
}
这将打印用户输入应用程序的名称,而不执行任何其他操作。任何帮助将不胜感激!
答案 0 :(得分:2)
您的计划有两个主要问题
$app
变量在您输入时按下的回车键的末尾包含换行符。这将阻止模式匹配,因此您需要使用chomp
删除它。这同样适用于从文件中读取的行
<$fh>
语句中的while
会将文件中的一行读入默认变量$_
,然后$line = <$fh>
读取另一行,因此您忽略来自文件的备用行
以下是我认为应该可以使用的程序版本,但我目前无法对其进行测试。我完全放弃了你的$line
变量,希望这不会让你感到困惑。 $_
是模式匹配的默认变量,因此不会在任何地方明确提及
use strict;
use warnings;
print "Enter the app: ";
my $app = <STDIN>;
chomp $app;
open my $fh, '<', 'eg.txt' or die "Cannot open: $!";
while ( <$fh> ) {
if ( /$app\s*=\s*(.+)/ ) {
my $path = $1;
$path =~ s/.*\.\.//;
print $path, "\n";
}
}
答案 1 :(得分:1)
输入在正则表达式中不匹配,因为换行符随之而来,所以最好使用chomp
来修剪它们。在while循环中,你取代了两倍的文件句柄,我不知道为什么。因此,在更正后,这应该有效:
use strict;
use warnings;
my $line = "";
my $app = "";
print "Enter the app";
chomp($app = <STDIN>);
print "$app: ";
open my $fh, '<', "eg.txt" or die "Cannot open $!";
while($line = <$fh>)
{
chomp $line;
if($line && $line =~ /($app)( = )(..\/)(..)(.*)/)
{
print "$5 \n";
}
}
close($fh);
答案 2 :(得分:0)
您在循环中访问<$fh>
两次。这将具有仅解释所有其他行的效果。您可能希望将循环顶部更改为以下内容:
while (defined(my $line = <$fh>)) {
并删除程序顶部的my $line ...
。
此外,您可能需要考虑选择输入行,这样您就不必考虑尾随换行符:
while (defined(my $line = <$fh>)) {
chomp $line;
你的正则表达式也有点冒险。您可能希望将其绑定到搜索空间的开头和结尾,并转义字面点。您可能还希望将$app
解释为字符串而不是正则表达式,这可以通过使用\Q...\E
包装来完成。除非你的文件格式指定了equals周围的单个空格,否则我很想将这些空间灵活地设置为零或更多。此外,如果你不打算使用早期的捕获,我会说不要这样做,所以:
if ($line && $line =~ /^\Q$app\E *= *\.\.\/\.\.(.*)$/)
{
print $1;
(有些人可能会说你应该使用\A
和\z
而不是^
和$
。这个选择留给了读者。)
答案 3 :(得分:0)
试试这段代码:
use strict;
use warnings;
my $line = "";
my $app = "";
print "Enter the app";
$app = <STDIN>;
print $app;
open my $fh, '<', "eg.txt" or die "Cannot open $!";
my @line = <$fh>;
my @fetch = map { /COMP\d+\s\=\s(\..\/\..\/.*)/g } @line ;
$, = "\n";
print @fetch;
然后请发送您的回复。