Remove first line of a file using perl -pe - perl

I'm trying to remove the first line of the output file "bss_concurrent_calls.txt" using perl -pe instead of system & sed -i. The server I'm using is solaris 9 (infact it didn't recognize "sed -i")
open my $file_in, "<", "/export/home/cassi/4.1-15_HPBX/cfg/LicenseCounters.log" or die($!);
open my $file_out, '>', 'bss_concurrent_calls.txt' or die $!;
while( <$file_in> ) {
my #columns = split /\s+/, $_;
print $file_out "$columns[0]\t$columns[2]\n";
}
system('sed "1d" bss_concurrent_calls.txt');
close $file_in;
close $file_out or die $!;

No need to call sed from Perl here (or anywhere else).
perl -ane 'print "$F[0]\t$F[2]\n" unless $. == 1' \
< /export/.../LicenseCounters.log > bss_concurrent_calls.txt

I like #choroba's answer, but if you want to keep your program structure:
use autodie;
open my $file_in, '<', '/export/home/cassi/4.1-15_HPBX/cfg/LicenseCounters.log';
open my $file_out, '>', 'bss_concurrent_calls.txt';
my $line1 = <$file_in>; # read the first line
while (<$file_in>) {
print $file_out join("\t", (split)[0,2]), "\n";
}
close $file_in;
close $file_out;

while( <$file_in> ) {
next unless $i++;
my #columns = split /\s+/, $_;
print $file_out "$columns[0]\t$columns[2]\n";
}

Related

To trim lines based on line number in perl

My Perl file generates the text file which usually contains 200 lines. Sometimes it exceeds 200 lines (For example 217 lines). I need to trim off the rest of the lines from the 201st line. I have used the counter method to trim the exceeded lines. Is there any other simple and efficient way to do this?
Code:
#!/usr/bin/perl -w
use strict;
use warnings;
my $filename1="channel.txt";
my $filename2="channel1.txt";
my $fh;
my $fh1;
my $line;
my $line1;
my $count=1;
open $fh, '<', $filename1 or die "Can't open > $filename1: $!";
open $fh1, '>', $filename2 or die "Can't open > $filename2: $!";
while(my $line = <$fh>)
{
chomp $line;
chomp $line1;
if($count<201)
{
print $fh1 "$line\n";
}
$count++;
}
close ($fh1);
close($fh);
I have already mentioned in my comment, this is short version of that comment If you actually trying to trim the file you can use the Perl One Liner instead of writing the whole code
perl -pe 'last if($. == 201);' input.text >result.txt
-p used for process the file line by line an print the output
-e execute flag, to execute the Perl syntax
With Perl script you can do this also
open my $fh,"<","input.txt";
open my $wh,">","result.txt";
print $wh scalar <$fh> for(1..10);
xxfelixxx already gave you the correct answer. I am just changing my earlier posted answer, to clean up your code and to write back to the original file:
use strict;
use warnings;
my #array;
my $filename="channel.txt";
open my $fh, '<', $filename or die "Can't open > $filename: $!";
while( my $line = <$fh> ) {
last if $. > 200;
push #array, $line;
}
close($fh);
open $fh, '>', $filename or die "Can't open > $filename: $!";
print $fh #array;
close($fh);
There is no need to keep your own counter, perl has a special variable $. which keeps track of the input line number. You can simplify your loop like so:
while( chomp( my $line = <$fh> ) ) {
last if $. > 200;
print $fh1 "$line\n";
}
perldoc perlvar - Search for INPUT_LINE_NUMBER.
To write back to the original file: input.txt without using redirection:
perl -pi.tmp -we "last if $.>200;" input.txt
where
-i : opens a temp file and automatically replaces the file to be
edited with the temporary file after processing (the '.tmp'
is the suffix to use for the temp file during processing)
-w : command line flag to 'use warnings'
-p : magic; basically equivalent to coding:
LINE: while (defined $_ = <ARGV>)) {
"your code here"
}
-e : perl code follows this flag (enclosed in double quotes for MSWin32 aficiandos)

Perl find and replace one liner

I've been looking at the other find and replace questions on Perl, and I'm not sure how exactly to implement this variation in one line. The only difference is that I want to replace two things, one is the original, and one is the replacing a modification of the original string. The code I have in a pm module is:
my $num_args = $#ARGV + 1;
if ($num_args != 2) {
print "\nUsage: pscript.pm path to file [VERSION]\n";
exit;
}
my $version = $ARGV[1];
my $revision = $ARGV[1];
$revision =~ s/.*\.//g;
open ($inHandle, "<", $ARGV[0]) or die $^E;
open ($outHandle, ">", "$ARGV[0].mod") or die $^E;
while(my $line = <$inHandle>)
{
$line =~ s/\<Foo\>(.*)\<\/Foo\>/\<Foo\>$version\<\/Foo\>/;
$line =~ s/\<Bar\>(.*)\<\/Bar\>/\<Bar\>$revision\<\/Bar\>/;
print $outHandle $line;
}
close $inHandle;
close $outHandle;
unlink $ARGV[0];
rename "$ARGV[0].mod", $ARGV[0];
What is different is:
$revision =~ s/.*\.//g;
which turns the version X.X.X.1000 into just 1000, and then uses that for the find and replace.
Can this be done using the
perl -i.bak -p -e 's/old/new/g;' *.config
format?
Try this :
perl -i.bak -pe 's/\d+\.\d+\.\d+\.1000\b/1000/g' *.config

How to call shell from perl script

Perl script reads url from config file. In config file data stored as URL=http://example.com.
How can I get site name only. I've tried
open(my $fh, "cut -d= -f2 'webreader.conf'");
But it doesn't work.
Please, help!
You have to indicate with reading pipe -| that what follows is command which gets forked,
open(my $fh, "-|", "cut -d= -f2 'webreader.conf'") or die $!;
print <$fh>; # print output from command
Better approach would be to read file directly by perl,
open( my $fh, "<", "webreader.conf" ) or die $!;
while (<$fh>) {
chomp;
my #F = split /=/;
print #F > 1 ? "$F[1]\n" : "$_\n";
}
Maybe something like this?
$ cat urls.txt
URL=http://example.com
URL=http://example2.com
URL=http://exampleXXX.com
$ ./urls.pl
http://example.com
http://example2.com
http://exampleXXX.com
$ cat urls.pl
#!/usr/bin/perl
$file='urls.txt';
open(X, $file) or die("Could not open file.");
while (<X>) {
chomp;
s/URL=//g;
print "$_\n";
}
close (X);

problems with replacing first line of file using perl

I have a file that looks like this:
I,like
blah...
I want to replace only the first line with 'i,am' to get:
i,am
blah...
These are big files, so this is what I did (based on this):
open(FH, "+< input.txt") or die "FAIL!";
my $header = <FH>;
chop($header);
$header =~ s/I,like/i,am/g;
seek FH, 0, 0; # go back to start of file
printf FH $header;
close FH;
However, I get this when I run it:
i,amke
blah...
I looks like the 'ke' from like is still there. How do I get rid of it?
What I would do is probably something like this:
perl -i -pe 'if ($. == 1) { s/.*/i,am/; }' yourfile.txt
Which will only affect the first line, when the line counter for the current file handle $. is equal to 1. The regex will replace everything except newline. If you need it to match your specific line, you can include that in the if-statement:
perl -i -pe 'if ($. == 1 and /^I,like$/) { s/.*/i,am/; }' yourfile.txt
You can also look into Tie::File, which allows you to treat the file like an array, which means you can simply do $line[0] = "i,am\n". It is mentioned that there may be performance issues with this module, however.
If the replacement has a different length than the original, you cannot use this technique. You can for example create a new file and then rename it to the original name.
open my $IN, '<', 'input.txt' or die $!;
open my $OUT, '>', 'input.new' or die $!;
my $header = <$IN>;
$header =~ s/I,like/i,am/g;
print $OUT $header;
print $OUT $_ while <$IN>; # Just copy the rest.
close $IN;
close $OUT or die $!;
rename 'input.new', 'input.txt' or die $!;
I'd just use Tie::File:
#! /usr/bin/env perl
use common::sense;
use Tie::File;
sub firstline {
tie my #f, 'Tie::File', shift or die $!;
$f[0] = shift;
untie #f;
}
firstline $0, '#! ' . qx(which perl);
Usage:
$ ./example
$ head -2 example
#! /bin/perl
use common::sense;

Unique element in file - perl

I want to get the unique elements (lines) from a file which I will further send through email.
I have tried 2 methods but both are not working:
1st way:
my #array = "/tmp/myfile.$device";
my %seen = ();
my $file = grep { ! $seen{ $_ }++ } #array;
2nd way :
my $filename = "/tmp/myfile.$device";
cat $filename |sort | uniq > $file
How can I do it?
You seem to have forgotten to read the file!
open(my $fh, '<', $file_name)
or die("Can't open \"$file_name\": $!\n");
my %seen;
my #unique = grep !$seen{$_}++, <$fh>;
You need to open the file and read it.
"cat" is a shell command not perl
Try something like this
my $F;
die $! if(!open($F,"/tmp/myfile.$device"));
my #array = <$F>;
my %seen = (); my $file = grep { ! $seen{ $_ }++ } #array;
The die $! will stop the program with an error if the file doesn't open correctly;
#array=<$F> reads all the data from the file $F opened above into the array.
If you rig the argument list, you can make Perl open the file automatically, using:
perl -n -e 'BEGIN{#ARGV=("/tmp/myfile.device");} print if $count{$_}++ == 0;'