Search for words ending with 'ing' from a text file in perl

落花浮王杯 提交于 2019-12-12 03:51:30

问题


I have a text file , lets call it file1.txt :

cats
and
dogs
are
running
around
|

john
loves
mary
|

I
am
swimming 
|

I am trying to build a program which looks for the words ending with 'ing' and prints CC beside them on the same file or to a different output.txt file.

Desired Output

cats
and
dogs
are
running  CC
around
|

john
loves
mary
|

I
am
swimming CC
|

I went through the available articles in the forum and tried building the following code ,however it gives me an arbitrary result with every word followed by " CC ".

use warnings;
use strict;

my $file = 'file1.txt';

open(my $word_fh,"file1.txt") or die "Couldn't open file file1.txt, $!";

my %word_match = map {chomp $_; $_ => 0} <$word_fh>;

close $word_fh;


open my $fh, '<', $file or die $!;

while (<$fh>){
    chomp;

    my @words_in_line = split;

    for my $word (@words_in_line){

        $word =~ /ing$/;
        $word .= '  CC' if exists $word_match{$word};

         print "    $word\n";
    }
    }

The output that I get is this :

cats    CC
and CC
dogs    CC
are CC
running CC
around  CC
|   CC
john    CC
loves   CC
mary    CC
|   CC
I   CC
am  CC
swimming
|   CC

I know I am doing something wrong. Any hints or suggestions would be appreciated. Thanks in advance !


回答1:


That's because you are reading your file1.txt twice and check whether they match. In the while loop you print 'CC' if the current line of file1.txt is also contained somewhere in file1.txt. Since they are the same files this is always true and 'CC' is printed after every line.

You might have been inspired by this question where the OP wanted to check whether words in file A are also contained in file B. Yours is a different case because you don't have two files.

Drop the first reading of file1.txt into %word_match and iterate over the file just once. Your line $word =~ /ing$/; only checks whether $word ends in ing but throws the result away. That is like writing

$i > 5;
print "i is greater than 5\n";

You have to change that to

if ( $i > 5 ) {
    print "i is greater than 5\n";
}

In summary this gives

#!/usr/bin/env perl

use strict;
use warnings;

open my $fh, '<', 'file1.txt' or die $!;
while ( <$fh> ){
    chomp;
    print $_;
    if ( /ing\s*$/ ) {
        print ' CC';
    }
    print "\n";
}
close($fh);



回答2:


It's not clear to me what your code is doing. What, for example, is the point of the %word_match hash? And why have you commented out use strict and use warnings?

It seems likely that you are over-thinking the problem as this seems pretty simple to me.

#!/usr/bin/perl
use strict;
use warnings;

while (<>) {
  chomp;
  $_ .= ' CCC' if /ing$/;
  print "$\n";
}

This is written as a Unix-style filter. It reads from STDIN and writes to STDOUT. So, (assuming it was in a file called cccing) you would call it like this:

$ ./cccing < your_input.txt > your_output.txt



回答3:


As others have commented, you are using your hash %word_match to test whether each word in the file exists in the same file. Of course that is true for every word, so you get a CC appended to everything

Removing the first open, the loop that builds the hash, and the test on the hash, I think this is the best way. It will handle multiple words per line as your own code does, and also avoids the need to allow for whitespace in the regex pattern

Perl code

use strict;
use warnings;

my $file = 'file1.txt';

open my $fh, '<', $file or die $!;

while ( <$fh> ){
    chomp;

    my @words_in_line = split;

    for my $word ( @words_in_line ) {

        $word .= ' CC' if $word =~ /(?:ing|s)$/;
    }

    print "    @words_in_line\n";
}

input

cats
and
dogs
are running around
|

john loves mary
|

I
am
swimming 
|

output

cats CC
and
dogs CC
are running CC around
|

john loves CC mary
|

I
am
swimming CC
|


来源:https://stackoverflow.com/questions/37905961/search-for-words-ending-with-ing-from-a-text-file-in-perl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!