如何在perl中使用数组索引删除单词?

时间:2017-02-15 08:51:18

标签: perl

如何使用Perl?

为以下输入使用数组索引删除某些单词?
file.txt
BOCK:top:blk1
BOCK:block2:blk2
BOCK:test:blk3

加入后:

/BOCK/top/blk1
/BOCK/block2/blk2
/BOCK/test/blk3

预期产出:

/BOCK/blk1
/BOCK/blk2
/BOCK/blk3

我曾尝试过的代码:

use warnings;
use strict;
my @words;
open(my $infile,'<','file.txt') or die $!;
while(<$infile>)
{
    push(@words,split /\:/);
}
my $word=join("/",@words);
print $word;
close ($infile);
foreach my $word(@words)
{
    if($word=~ /(\w+\/\w+\/\w+)/)
    {
        print $word;
    }
}

2 个答案:

答案 0 :(得分:4)

摆脱中间元素的最简单方法是使用splice

while ( my $line = <DATA> ) {
    my @words;
    push( @words, split( /:/, $line ) );    # colon has no special meaning
    splice( @words, 1, 1 );
    print '/', join( '/', @words );
}

__DATA__
BOCK:top:blk1
BOCK:block2:blk2
BOCK:test:blk3

我认为你想为每一行做到这一点。你所拥有的代码做了别的事情。由于您的@words声明在while循环之外,因此每次迭代都会变大,而每个第三个元素都包含换行符\n,因为您永远不会chomp。然后,您构建一个长$word,其中包含所有使用斜杠/连接的行中的所有单词。然后你尝试匹配三个用斜线连接的单词,这有效。但是您只有一个捕获组,因此永远不会定义$3

答案 1 :(得分:2)

代码可以简化和清理,甚至到

my @paths = map { '/' . join '/', (split ':')[0,-1] } <$infile>;

print "$_\n" for @paths;

map在文件句柄读取上强加列表上下文,从而返回文件中所有行的列表。 map块中的代码应用于每个元素:它split是该行,并获取该列表的第一个和最后一个元素,join是它们,然后预先引导/。在块内,该行位于variable $_split默认使用。返回结果列表并将其分配给@path

已在simbabque's answer中明确说明了已发布代码中的一些错误。

感谢jm666在评论中发现领先/的要求。

以上也可用于单线

perl -F: -lane'print "/" . join "/", @F[0,-1]' < file.txt  > out.txt

-a启用自动分割模式(使用-n-p),每行都会被分割并在@F中可用。 -F开关允许指定要拆分的模式,此处为:,而不是默认空间。

请参阅switches in perlrun