Perl Search for string and print out line - perl

I want to write a perl script that ask the user for a string and then finds the lines that contains that string and prints them.
This is what i have so far
#!/usr/bin/perl
use strict;
use warnings;
sub main
{
print "First name or Last Name or any portion: ";
my $name = <STDIN>;
my $file = '/home/jake/Downloads/phones';
open(FH, $file) or die("File $file not found");
while(my $String = <FH>)
{
if($String =~ $name)
{
print "$String \n";
}
}
close(FH);
}
main();
Whenever I try this the terminal doesnt print anything. Is there anything that I could do to fix that?

Try this out:
#!/usr/bin/perl
use strict;
use warnings;
sub main
{
print "First name or Last Name or any portion: ";
my $name = <STDIN>;
chomp $name;
my $file = '/home/jake/Downloads/phones';
open my $fh, '<', $file or die "$file: $!\n";
while(my $string = <$fh>)
{
if($string =~ /$name/)
{
print "$string\n";
}
}
close($fh);
}
main();
You need to omit the new line character using chomp.
Use a modern way to read a file, using a lexical filehandle.

Related

Printing value from split result Perl

Here I have a abc.txt file:
aaa,1000,kevin
bbb,2000,john
ccc,3000,jane
ddd,4000,kevin
Then I want to print out:
kevin
john
jane
my Perl script is:
open (INFILE, $ARGV[1]) or die "An input file is required as argument\n";
#store=();
while(<INFILE>)
{
chomp();
#data=split(/,/);
#
#
#
if (%store ne "0")
{
print "Printing users:\n";
foreach $key (keys %store)
{print $key."\n";}
}
print "Printing users:\n";
foreach $key (keys %store)
{print $key."\n";}
}
My idea is to store the value into hash and create key to each value. How can I do in the ### line?
You have declared #store and then using %store. I didn't understand that why you doing that, but the below code will give you desire output. First read the input file, split the data and then remove the duplicates.
use strict;
use warnings;
my $infile = $ARGV[0];
open my $fh, "<", $infile or die "An input file is required as argument: $!";
my %store;
while(my $line = <$fh>)
{
chomp($line);
my #data = split /,/, $line;
my #removeduplicate = (grep { !$store{$_}++ } #data)[2];
foreach(#removeduplicate){
if( $_ ne ''){
print "$_\n";
}
}
}
close $fh;
Output:
kevin
john
jane
hmmm. it depends what do you want. maybe this example will help you:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper; #for debug if you want
my $infile='abc.txt'; #or ARGV[0] whatever it is
my $fh;
open $fh,'<',$infile or die "problem with $infile $# $!";
my $inputline;
my %Storage;
my #Values;
while (defined($inputline=<$fh>)) {
chomp $inputline;
#Values=split ',',$inputline;
if (#Values != 3) {
warn "$inputline has formatted badly";
next;
}
#warn if exists $Storage{$Values[1]}; #optional warning for detected duplicates
$Storage{$Values[1]}=#Values[0,2]; #create hash data
#duplicates will be removed automaticly
}
close $fh;
print Dumper \%Storage; #print how perl it stores
foreach my $Key (keys %Storage) { #example loop
print #{Storage->{$Key}},"\n"; #do anything
}
I hope this template will be enough for you.

Add headings to the a text file in perl

I have a text file with the following lines as example
This is line
This is line with test
This is ine with 2test
This is line 2
This is line 3
This is line with 3test
This is line 4
This is line with 4test
Now I want a code to change the text file as follows:
Lines with test
This is line with test
This is ine with 2test
This is line with 3test
This is line with 4test
Lines without test
This is line
This is line 2
This is line 3
This is line 4
I am using the following code. I am assuming my code would print the title with every line but I am not able to execute the code due to some errors.
Can you please help me?
#!/usr/bin/perl
use strict;
use warnings;
open(FH, '<filetest.txt');
my #queues = <FH>;
close(FH);
open(OFH,'>testfile.txt');
my $name;
foreach $name(#queues)
{
if($name =~ 'test')
{
print OFH "Lines with test\n";
print OFH $1;
}
else{
print OFH "Lines without test\n";
print OFH $1;
}
close(OFH);
}
Note: I corrected the error to remove the syntax errors but still there is nothing being written to the file testfile.txt
Have a try with:
#!/usr/bin/perl
use strict;
use warnings;
my $infile = 'filetest.txt';
my $outfile = 'testfile.txt';
# use 3-arg open and if open succeeded
open my $fh_in, '<', $infile or die "Unable to open file '$infile' for reading: $!";
my #with_test;
my #without_test;
while (<$fh_in>) {
if (/test/) {
push #with_test, $_;
} else {
push #without_test, $_;
}
}
close $fh_in;
open my $fh_out, '>', $outfile or die "Unable to open file '$outile' for writting: $!";
print $fh_out "Lines with test\n";
print $fh_out #with_test;
print $fh_out "Lines without test\n";
print $fh_out #without_test;
close $fh_out;
I haven't tested this. The idea is to write the "with test" lines to the file immediately
The "without test" lines are stored (in an array called "without") until the end of the program and then written
#!/usr/bin/perl
use strict;
use warnings;
open(FH, '<filetest.txt');
my #queues = <FH>;
close(FH);
open(OFH,'>testfile.txt');
my $name;
my #without=();
foreach $name(#queues)
{
if($name =~ 'test')
{
print OFH $name;
}
else{
push #without, $name;
}
print OFH "\n\nlines without\n";
print OFH #without;
}
also you should add a local $/ before reading the file handle.
check this out:
how to read the whole file.
the match format should be like this: if($somestr =~ /#/).
and you shouldn't close the filehandle in the loop.
#!/usr/bin/perl
use strict;
use warnings;
local $/;
open(FH, 'file#.txt');
my $s;
$s = <FH>;
close(FH);
open(FH, '>file#.txt');
my #queues = split(/\n/, $s);
my #arr;
my #arr2;
for($s=0; $s<$#queues+1; $s++)
{
if($queues[$s] =~ /#/)
{
push(#arr, $queues[$s]."\n");
}
else
{
push(#arr2, $queues[$s]."\n");
}
}
print FH "lines with #\n";
print FH #arr;
print FH "lines without #\n";
print FH #arr2;

Extracting specific multiple line of records that is pipe delimited in perl

I have a file that looks like
NAME|JOHN|TOKYO|JPN
AGE|32|M
INFO|SINGLE|PROFESSIONAL|IT
NAME|MARK|MANILA|PH
AGE|37|M
INFO|MARRIED|PROFESSIONAL|BPO
NAME|SAMANTHA|SYDNEY|AUS
AGE|37|F
INFO|MARRIED|PROFESSIONAL|OFFSHORE
NAME|LUKE|TOKYO|JPN
AGE|27|M
INFO|SINGLE|PROFESSIONAL|IT
I want to separate the records by country. I have stored each line into array variable #fields
my #fields = split(/\|/, $_ );
making $fields[3] as my basis for sorting it. I wanted it to separate into 2 output text files
OUTPUT TEXT FILE 1:
NAME|JOHN|TOKYO|JPN
AGE|32|M
INFO|SINGLE|PROFESSIONAL|IT
NAME|LUKE|TOKYO|JPN
AGE|27|M
INFO|SINGLE|PROFESSIONAL|IT
OUTPUT TEXT FILE 2
NAME|MARK|MANILA|PH
AGE|37|M
INFO|MARRIED|PROFESSIONAL|BPO
NAME|SAMANTHA|SYDNEY|AUS
AGE|37|F
INFO|MARRIED|PROFESSIONAL|OFFSHORE
Putting all that is from JPN to output text 1 & non-JPN country to output text file 2
here's the code that what trying to work out
use strict;
use warnings;
use Data::Dumper;
use Carp qw(croak);
my #fields;
my $tmp_var;
my $count;
;
my ($line, $i);
my $filename = 'data.txt';
open(my $input_fh, '<', $filename ) or croak "Can't open $filename: $!";
open(OUTPUTA, ">", 'JPN.txt') or die "wsl_reformat.pl: could not open $ARGV[0]";
open(OUTPUTB, ">", 'Non-JPN.txt') or die "wsl_reformat.pl: could not open $ARGV[0]";
my $fh;
while (<$input_fh>) {
chomp;
my #fields = split /\|/;
if ($fields[0] eq 'NAME') {
for ($i=1; $i < #fields; $i++) {
if ($fields[3] eq 'JPN') {
$fh = $_;
print OUTPUTA $fh;
}
else {
$fh = $_;
print OUTPUTB $fh;
}
}
}
}
close(OUTPUTA);
close(OUTPUTB)
Still has no luck on it :(
Here is the way I think ikegami was saying, but I've never tried this before (although it gave the correct results).
#!/usr/bin/perl
use strict;
use warnings;
open my $jpn_fh, ">", 'o33.txt' or die $!;
open my $other_fh, ">", 'o44.txt' or die $!;
my $fh;
while (<DATA>) {
if (/^NAME/) {
if (/JPN$/) {
$fh = $jpn_fh;
}
else {
$fh = $other_fh;
}
}
print $fh $_;
}
close $jpn_fh or die $!;
close $other_fh or die $!;
__DATA__
NAME|JOHN|TOKYO|JPN
AGE|32|M
INFO|SINGLE|PROFESSIONAL|IT
NAME|MARK|MANILA|PH
AGE|37|M
INFO|MARRIED|PROFESSIONAL|BPO
NAME|SAMANTHA|SYDNEY|AUS
AGE|37|F
INFO|MARRIED|PROFESSIONAL|OFFSHORE
NAME|LUKE|TOKYO|JPN
AGE|27|M
INFO|SINGLE|PROFESSIONAL|IT
You didn't say what you needed help with, so I'm assuming it's coming up with an algorithm. Here's a good one:
Open the file to read.
Open the file for the JPN entries.
Open the file for the non-JPN entries.
While not eof,
Read a line.
Parse the line.
If it's the first line of a record,
If the person's country is JPN,
Set current file handle to the file handle for JPN entries.
Else,
Set current file handle to the file handle for non-JPN entries.
Print the line to the current file handle.
my $jpn_qfn = '...';
my $other_qfn = '...';
open(my $jpn_fh, '>', $jpn_qfn)
or die("Can't create $jpn_qfn: $!\n");
open(my $other_fh, '>', $other_qfn)
or die("Can't create $other_qfn: $!\n");
my $fh;
while (<>) {
chomp;
my #fields = split /\|/;
if ($fields[0] eq 'NAME') {
$fh = $fields[3] eq 'JPN' ? $jpn_fh : $other_fh;
}
say $fh $_;
}
#!/usr/bin/env perl
use 5.012;
use autodie;
use strict;
use warnings;
# store per country output filehandles
my %output;
# since this is just an example, read from __DATA__ section
while (my $line = <DATA>) {
# split the fields
my #cells = split /[|]/, $line;
# if first field is NAME, this is a new record
if ($cells[0] eq 'NAME') {
# get the country code, strip trailing whitespace
(my $country = $cells[3]) =~ s/\s+\z//;
# if we haven't created and output file for this
# country, yet, do so
unless (defined $output{$country}) {
open my $fh, '>', "$country.out";
$output{$country} = $fh;
}
my $out = $output{$country};
# output this and the next two lines to
# country specific output file
print $out $line, scalar <DATA>, scalar <DATA>;
}
}
close $_ for values %output;
__DATA__
NAME|JOHN|TOKYO|JPN
AGE|32|M
INFO|SINGLE|PROFESSIONAL|IT
NAME|MARK|MANILA|PH
AGE|37|M
INFO|MARRIED|PROFESSIONAL|BPO
NAME|SAMANTHA|SYDNEY|AUS
AGE|37|F
INFO|MARRIED|PROFESSIONAL|OFFSHORE
NAME|LUKE|TOKYO|JPN
AGE|27|M
INFO|SINGLE|PROFESSIONAL|IT
Thanks for your Help heaps
I was able to solved this problem in perl,
many thanks
#!/usr/local/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Carp qw(croak);
my #fields;
my $tmp_var;
my ($rec_type, $country);
my $filename = 'data.txt';
open (my $input_fh, '<', $filename ) or croak "Can't open $filename: $!";
open my $OUTPUTA, ">", 'o33.txt' or die $!;
open my $OUTPUTB, ">", 'o44.txt' or die $!;
my $Combline;
while (<$input_fh>) {
$_ = _trim($_);
#fields = split (/\|/, $_);
$rec_type = $fields[0];
$country = $fields[3];
if ($rec_type eq 'NAME') {
if ($country eq 'JPN') {
*Combline = $OUTPUTA;
}
else {
*Combline = $OUTPUTB;
}
}
print Combline;
}
close $OUTPUTA or die $!;
close $OUTPUTB or die $!;
sub _trim {
my $word = shift;
if ( $word ) {
$word =~ s/\s*\|/\|/g; #remove trailing spaces
$word =~ s/"//g; #remove double quotes
}
return $word;
}

Using perl, how do I search a text file for _NN (at the end of a word) and print the word in front?

This gives the whole line:
#!/usr/bin/perl
$file = 'output.txt';
open(txt, $file);
while($line = <txt>) {
print "$line" if $line =~ /_NN/;
}
close(txt);
#!/usr/bin/perl
use strict;
use warnings FATAL => "all";
binmode(STDOUT, ":utf8") || die;
my $file = "output.txt";
open(TEXT, "< :utf8", $file) || die "Can't open $file: $!";
while(<TEXT>) {
print "$1\n" while /(\w+)_NN\b/g;
}
close(TEXT) || die "Can't close $file: $!";
Your answer script reads a bit awkwardly, and has a couple of potential errors. I'd rewrite the main logic loop like so:
foreach my $line (grep { /expend_VB/ } #sentences) {
my #nouns = grep { /_NN/ } split /\s+/, $line;
foreach my $word (#nouns) {
$word =~ s/_NN//;
print "$word\n";
}
print "$line\n" if scalar(#nouns);
}
You need to put the my declaration inside the loop - otherwise it will persist longer than you want it to, and could conceivably cause problems later.
foreach is a more common perl idiom for iterating over a list.
print "$1" if $line =~ /(\S+)_NN/;
#!/usr/bin/perl
use strict;
use warnings FATAL => "all";
my $search_key = "expend"; ## CHANGE "..." to <>
open(my $tag_corpus, '<', "ch13tagged.txt") or die $!;
my #sentences = <$tag_corpus>; # This breaks up each line into list
my #words;
for (my $i=0; $i <= #sentences; $i++) {
if ( defined( $sentences[$i] ) and $sentences[$i] =~ /($search_key)_VB.*/i) {
#words = split /\s/,$sentences[$i]; ## \s is a whitespace
for (my $j=0; $j <= #words; $j++) {
#FILTER if word is noun:
if ( defined( $words[$j] ) and $words[$j] =~ /_NN/) {
#PRINT word and sentence:
print "**",split(/_\S+/,$words[$j]),"**", "\n";
print split(/_\S+/,$sentences[$i]), "\n"
}
} ## put print sentences here to print each sentence after all the nouns inside
}
}
close $tag_corpus || die "Can't close $tag_corpus: $!";

Perl - Searching a file for specific text and deleting a range of lines [duplicate]

This question already has an answer here:
Closed 12 years ago.
Possible Duplicate:
How do I change, delete, or insert a line in a file, or append to the beginning of a file in Perl?
How would I use perl to open up a file, look for an item that someone inputs, and if it is found, it will delete from that line to 14 lines below.
Something like this will work:
#!/usr/bin/env perl
use Modern::Perl;
use IO::File;
say "Enter a pattern please: ";
chomp (my $input = <>);
my $pattern;
# check that the pattern is good
eval {
$pattern = qr ($input);
}; die $# if $#;
my $fh = IO::File->new("test.txt", "+<") or die "$!\n";
my #lines = $fh->getlines;
$fh->seek(0,0);
for (my $pos = 0; $pos < $#lines; ++$pos) {
if ($lines[$pos] =~ $pattern) {
$pos += 14;
} else {
print {$fh} $lines[$pos];
}
}
$fh->close;
$|++
#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
my $filename = 'filename.txt';
my $tmp = 'filename.txt.tmp';
print "Enter a pattern please: ";
chomp (my $input = <>);
my $pattern = qr($input)x;
open my $i_fh, '+<', $filename;
open my $o_fh, '>', $tmp;
while(<$i_fh>){
# move print here if you want to print the matching line
if( /$pattern/ ){
<$i_fh> for 1..14;
next;
}
print {$o_fh} $_ ;
}
close $o_fh;
close $i_fh;
use File::Copy
move $tmp, $filename;