Perl search for string and get the full line from text file - perl

I want to search for a string and get the full line from a text file through Perl scripting.
So the text file will be like the following.
data-key-1,col-1.1,col-1.2
data-key-2,col-2.1,col-2.2
data-key-3,col-3.1,col-3.2
Here I want to apply data-key-1 as the search string and get the full line into a Perl variable.
Here I want the exact replacement of grep "data-key-1" data.csv in the shell.
Some syntax like the following worked while running in the console.
perl -wln -e 'print if /\bAPPLE\b/' your_file
But how can I place it in a script? With the perl keyword we can't put it into a script. Is there a way to avoid the loops?

If you'd know the command line options you are giving for your one-liner, you'd know exactly what to write inside your perl script. When you read a file, you need a loop. Choice of loop can yield different results performance wise. Using for loop to read a while is more expensive than using a while loop to read a file.
Your one-liner:
perl -wln -e 'print if /\bAPPLE\b/' your_file
is basically saying:
-w : Use warnings
-l : Chomp the newline character from each line before processing and place it back during printing.
-n : Create an implicit while(<>) { ... } loop to perform an action on each line
-e : Tell perl interpreter to execute the code that follows it.
print if /\bAPPLE\b/ to print entire line if line contains the word APPLE.
So to use the above inside a perl script, you'd do:
#!usr/bin/perl
use strict;
use warnings;
open my $fh, '<', 'your_file' or die "Cannot open file: $!\n";
while(<$fh>) {
my $line = $_ if /\bAPPLE\b/;
# do something with $line
}
chomp is not really required here because you are not doing anything with the line other then checking for an existence of a word.

open($file, "<filename");
while(<$file>) {
print $_ if ($_ =~ /^data-key-3,/);
}

use strict;
use warnings;
# the file name of your .csv file
my $file = 'data.csv';
# open the file for reading
open(FILE, "<$file") or
die("Could not open log file. $!\n");
#process line by line:
while(<FILE>) {
my($line) = $_;
# remove any trail space (the newline)
# not necessary, but again, good habit
chomp($line);
my #result = grep (/data-key-1/, $line);
push (#final, #result);
}
print #final;

Related

From inside a perl script can you know the name of the file you are redirecting output to?

So I have:
test.pl > test.log
is there a way to know inside test.pl that I am outputing to 'test.log'? At the end of my script I want to do some manipulation of test.log without hardcoding the name.
Maybe. The following works on Linux, but will not be very portable to other systems...
#!/usr/bin/env perl
use strict;
use warnings;
my $out = readlink("/proc/$$/fd/1");
print STDERR "I am being output to $out\n";
Naturally, this is probably a bad idea. Better to explicitly open the file and write to it in Perl, rather than having the shell set up redirections.
You can redirect standard output from perl, with minimal changes to your script,
test.pl test.log
my ($file) = #ARGV;
if (#ARGV) {
open STDOUT, ">", $file or die $!;
}
print "output is redirected to $file\n";
# use $file at the end

Create files from text list using command line?

I know that normally you can just use touch filename to create new files via command line. But, in the text file I have a list of about 500 cities and states, each on a new line. I need to use command line to create a new text file for each of the cities/states. For example, Texas.txt, New York.txt, California.txt
The name of the file that contains the list is newcities.txt - Is this possible to do in command line or through Perl?
You can do this directly in the shell, no need for perl
cat myfile | while read f; do echo "Creating file $f"; touch "$f"; done
perl -lnwe 'open my $fh,">", "$_.txt" or die "$_: $!";' cities.txt
Using the -l option to autochomp the input. The open will create a new empty file, and the file handle will be autoclosed when it goes out of scope.
how about a simple:
cat fileName | xargs touch
Here's a one-liner in perl, assuming each city is on a new line
perl -ne 'chomp; `touch $_`;' newcities.txt
Here's the script version:
#!/usr/bin/perl
use warnings;
use strict;
open my $fh, "<", "./newcities.txt"
or die "Cannot open file: $!";
while( my $line = <$fh> ){
chomp $line;
system("touch $line");
}
close $fh;

Perl script to copy rows to place in new file

I have a lot of text files in a folder. The folder is 'c:\vehicles'. For every text file, I want to copy any row that includes the words: model, make, year. The file I want to write to is 'vehicles.txt' and located in 'c:\'.
I know I've written the code wrong. What should I do to correct it? Thanks for the help.
C:\vehicles $ ls -A | xargs head -qn 30 | perl -Mstrict -wne 'if( $ +_ =~ /(make)|(model)|(year)/ ) { print "$_"; }' > vehicles.txt
grep -rE "(make|model|year)" c:
Perhaps the following will help:
use strict;
use warnings;
for my $file (<*.txt>) {
open my $fh, '<', $file or die $!;
while (<$fh>) {
chomp;
print "$_\n" if /(?:\b(?:model|make|year)\b)/i;
}
close $fh;
}
Assuming the script will be in c:\vehicles, type perl scriptName.pl >vehicles.txt at the command prompt.
The <*.txt> notation returns a list of all text files in the directory. Each of these files are opened and read, line by line. If any of the words your looking for are found on a line, it's printed. The >vehicles.txt notation means to print to the file.

Perl Script to Read File Line By Line and Run Command on Each Line

I found this perl script here which seems will work for my purposes. It opens a Unicode text file and reads each line so that a command can be run. But I cannot figure out how to run a certain ICU command on each line. Can someone help me out? The error I get is (largefile is the script name):
syntax error at ./largefile line 11, near "/ ."
Search pattern not terminated at ./largefile line 11.
#!/usr/bin/perl
use strict;
use warnings;
my $file = 'test.txt';
open my $info, $file or die "Could not open $file: $!";
while( my $line = <$info>) {
do
LD_LIBRARY_PATH=icu/source/lib/ ./a.out "$line" >> newtext.txt
done
}
close $info;
Basically I want to open a large text file and run the command (which normally runs from the command line...I think how I call this in the perl script is the problem, but I don't know how to fix it) "LD_LIBRARY_PATH=icu/source/lib/ ./a.out "$line" >> newtext.txt" on each line so that "newtext.txt" is then populated with all the lines after they have been processed by the script. The ICU part is breaking words for Khmer.
Any help would be much appreciated! I'm not much of a programmer... Thanks!
For executing terminal commands, the command needs to be in system(), hence change to
system("LD_LIBRARY_PATH=icu/source/lib/ ./a.out $line >> newtext.txt");
Have you tried backticks:
while (my $line = <$info>) {
`LD_LIBRARY_PATH=icu/source/lib/ ./a.out "$line" >> newtext.txt`
last if $. == 2;
}

How to read multiple files from a directory, extract specific strings and ouput to an html file?

Greetings,
I have the following code and am stuck on how I would proceed to modify it so it will ask for the directory, read all files in the directory, then extract specific strings and ouput to an html file? Thanks in advance.
#!/usr/local/bin/perl
use warnings;
use strict;
use Cwd;
print "Enter filename: "; # Should be Enter directory
my $perlfile =STDIN;
open INPUT_FILE, $perlfile || die "Could not open file: $!";
open OUTPUT, '>out.html' || die "Could not open file: $!";
# Evaluates the file and imports it into an array.
my #comment_array = ;
close(INPUT_FILE);
chomp #comment_array;
#comment_array = grep /^\s*#/g, #comment_array;
my $comment;
foreach $comment (#comment_array) {
$comment =~ /####/; #Pattern match to grab only #s
# Prints comments to screen
Print results in html format
# Writes comments to output.html
Writes results to html file
}
close (OUTPUT);
Take it one step at a time. You have a lot planned, but so far you haven't even changed your prompt string to ask for a directory.
To read the entered directory name, your:
my $perlfile =STDIN;
gives an error (under use strict;). Start by looking that error up (use diagnostics; automates this) and trying to figure out what you should be doing instead.
Once you can prompt for a directory name and print it out, then add code to open the directory and read the directory. Directories can be opened and read with opendir and readdir. Make sure you can read the directory and print out the filenames before going on to the next step.
a good starting point to learn about specific functions (from the cmd line)
perldoc -f opendir
However, your particular problem is answered as follows, you can also use command line programs and pipe them into a string to simplify file handling ('cat') and pattern matching ('grep').
#!/usr/bin/perl -w
use strict;
my $dir = "/tmp";
my $dh;
my #patterns;
my $file;
opendir($dh,$dir);
while ($file = readdir($dh)){
if (-f "$dir/$file"){
my $string = `cat $dir/$file | grep pattern123`;
push #patterns, $string;
}
}
closedir($dh);
my $html = join("<br>",#patterns);
open F, ">out.html";
print F $html;
close F;