perl: adding lines and replacing stings

E

erobinson32

I would like to do three things in a single Perl script:
1. Add the text "FirstLine" to the very first line of a sample file.
2. Add the test "LastLine" to the very last line of a sample file.
3. Replace all of the instances of 'California' to 'Nevada' in a file.

I've just been running a few commands to accomplish this, but would
like to simplify the process:

perl -pi -e 's/California/Nevada/g' testfile
sed '1i\
FirstLine' testfile > temp_file
mv temp_file testfile
sed '$a\
LastLine' testfile > temp_file
mv temp_file testfile


Original File:
test1 - California
test2 - Oregon
test3 - Texas

Updated File:
FirstLine
test1 - Nevada
test2 - Oregon
test3 - Texas
LastLine

Is this possible? If not, is there a more automatic way of doing
this? updating my .bashrc?
 
P

Paul Lalli

I would like to do three things in a single Perl script:
1. Add the text "FirstLine" to the very first line of a sample file.
2. Add the test "LastLine" to the very last line of a sample file.
3. Replace all of the instances of 'California' to 'Nevada' in a file.

I've just been running a few commands to accomplish this, but would
like to simplify the process:

perl -pi -e 's/California/Nevada/g' testfile
sed '1i\
FirstLine' testfile > temp_file
mv temp_file testfile
sed '$a\
LastLine' testfile > temp_file
mv temp_file testfile

Original File:
test1 - California
test2 - Oregon
test3 - Texas

Updated File:
FirstLine
test1 - Nevada
test2 - Oregon
test3 - Texas
LastLine

Is this possible? If not, is there a more automatic way of doing
this? updating my .bashrc?

This is a Perl "one-liner", though in this case, that's rather a
misnomer...

$ cat sample.txt
test1 - California
test2 - Oregon
test3 - Texas

$ perl -pi -e'
$_ = "First Line\n$_" if $. == 1;
s/California/Nevada/;
$_ .= "Last Line\n" if eof;
' sample.txt

$ cat sample.txt
First Line
test1 - Nevada
test2 - Oregon
test3 - Texas
Last Line

Read more about the various command line options in
perldoc perlrun
And see also:
perldoc perlvar (for $.)
perldoc -f eof

Hope this helps,
Paul Lalli
 
K

Kalyan Manchikanti

I would like to do three things in a single Perl script:
1. Add the text "FirstLine" to the very first line of a sample file.
2. Add the test "LastLine" to the very last line of a sample file.
3. Replace all of the instances of 'California' to 'Nevada' in a file.

I've just been running a few commands to accomplish this, but would
like to simplify the process:

perl -pi -e 's/California/Nevada/g' testfile
sed '1i\
FirstLine' testfile > temp_file
mv temp_file testfile
sed '$a\
LastLine' testfile > temp_file
mv temp_file testfile

Original File:
test1 - California
test2 - Oregon
test3 - Texas

Updated File:
FirstLine
test1 - Nevada
test2 - Oregon
test3 - Texas
LastLine

Is this possible? If not, is there a more automatic way of doing
this? updating my .bashrc?

perldoc -f unshift ( to add a first line to your existing file)..
perldoc -f push ( to add a last line to your existing file)..
perldoc -f tr, perldoc -f substr and ofcourse s/ ..are just three of
the many ways you can achieve string substitution..
 
P

Paul Lalli

perldoc -f unshift ( to add a first line to your existing file)..
perldoc -f push ( to add a last line to your existing file)..

Gah. You are suggesting the OP read the entire file into memory,
modify the array, and then print the entire array back to the file?
Please don't do this. Ever.

Paul Lalli
 
E

erobinson32

This is a Perl "one-liner", though in this case, that's rather a
misnomer...

$ cat sample.txt
test1 - California
test2 - Oregon
test3 - Texas

$ perl -pi -e'
$_ = "First Line\n$_" if $. == 1;
s/California/Nevada/;
$_ .= "Last Line\n" if eof;
' sample.txt

$ cat sample.txt
First Line
test1 - Nevada
test2 - Oregon
test3 - Texas
Last Line

Read more about the various command line options in
perldoc perlrun
And see also:
perldoc perlvar (for $.)
perldoc -f eof

Hope this helps,
Paul Lalli

Thanks Paul, that worked great!
 
B

Ben Morrow

Quoth "erobinson32 said:
I would like to do three things in a single Perl script:
1. Add the text "FirstLine" to the very first line of a sample file.
2. Add the test "LastLine" to the very last line of a sample file.
3. Replace all of the instances of 'California' to 'Nevada' in a file.

I've just been running a few commands to accomplish this, but would
like to simplify the process:

perl -pi -e 's/California/Nevada/g' testfile
sed '1i\
FirstLine' testfile > temp_file
mv temp_file testfile
sed '$a\
LastLine' testfile > temp_file
mv temp_file testfile

You're nearly there :)

perl -pi -le'
BEGIN { print "FirstLine" }
s/California/Nevada/g;
END { print "LastLine" }'

Ben
 
U

Uri Guttman

PL> Gah. You are suggesting the OP read the entire file into memory,
PL> modify the array, and then print the entire array back to the file?
PL> Please don't do this. Ever.

why not? if the file is small enough (and small is pretty big by today's
ram standards) it is simpler and faster to slurp in many cases. this
could be done with:

use File::Slurp ;

my $text = read_file( 'file' ) ;
$text =~ s/Nevada/California/g ;
write_file( 'file', "FirstLine\n", $text, "LastLine\n" ) ;

and when the edit_file feature is added it would be something like:

edit_file( 'file', sub{ s/Nevada/California/g ;
$_ = "FirstLine\n${_}LastLine\n" } ) ;

i totally get line by line processing but the bias against slurping
small files is silly IMO. with stdio or filesystem buffer sizes like 64k
now, you don't save any real ram with line by line and slurping usually
will be faster.

uri
 
P

Paul Lalli

PL> Gah. You are suggesting the OP read the entire file into memory,
PL> modify the array, and then print the entire array back to the file?
PL> Please don't do this. Ever.

why not? if the file is small enough (and small is pretty big by today's
ram standards) it is simpler and faster to slurp in many cases.

Because far too many people program via the "copy-and-paste" method,
rather than the "think" method, and when they see a piece of code that
modifies a file by slurping it, they won't stop to think that the
method isn't as valid for their situation just because their file is
obscenely larger.

I just don't see the point of using a method that's only sometimes
valid as opposed to using one that's always valid.

Paul Lalli
 
P

Paul Lalli

Quoth "erobinson32" <[email protected]>:










You're nearly there :)

perl -pi -le'
BEGIN { print "FirstLine" }
s/California/Nevada/g;
END { print "LastLine" }'

Uhm, you're not, unfortunately. :p Did you actually try this? The -
i feature takes affect only during the while(<>) {} loop created by -
p, and BEGIN{} and END{} blocks happen outside that loop. End result
- the two blocks print to STDOUT rather than the file.

Paul Lalli
 
B

Ben Morrow

Quoth "Paul Lalli said:
Uhm, you're not, unfortunately. :p Did you actually try this?

Well, clearly not. Sorry about that :(.
The -i feature takes affect only during the while(<>) {} loop created
by -p, and BEGIN{} and END{} blocks happen outside that loop. End
result - the two blocks print to STDOUT rather than the file.

Yes, of course... and there I thought I was being so clever :(. Ach
well.

Ben
 
U

Uri Guttman

PL> Gah. You are suggesting the OP read the entire file into memory,
PL> modify the array, and then print the entire array back to the file?
PL> Please don't do this. Ever.
PL> Because far too many people program via the "copy-and-paste" method,
PL> rather than the "think" method, and when they see a piece of code that
PL> modifies a file by slurping it, they won't stop to think that the
PL> method isn't as valid for their situation just because their file is
PL> obscenely larger.

PL> I just don't see the point of using a method that's only sometimes
PL> valid as opposed to using one that's always valid.

for those who do think and like/need speed and in many cases simplicity,
it is more than just valid. like i said teaching line by line is good
but not the only nor always the best way.

and the determination of obscenely large is very vague. most text files
that need processing are articles, code source, config files, etc. the
large ones are notably logs and genetic data. so in most cases it is
pretty easy to know if slurping will work fine. you general know the
type of file you are processing unless you are making a truly general
program like grep.

uri
 
J

John W. Krahn

Uri said:
PL> Gah. You are suggesting the OP read the entire file into memory,
PL> modify the array, and then print the entire array back to the file?
PL> Please don't do this. Ever.

why not? if the file is small enough (and small is pretty big by today's
ram standards) it is simpler and faster to slurp in many cases. this
could be done with:

use File::Slurp ;

my $text = read_file( 'file' ) ;
$text =~ s/Nevada/California/g ;
write_file( 'file', "FirstLine\n", $text, "LastLine\n" ) ;


perl -i -0777ne's/Nevada/California/g; print "FirstLine\n${_}LastLine\n"'




John
 
T

Tad McClellan

Ben Morrow said:
Well, clearly not. Sorry about that :(.


Yes, of course... and there I thought I was being so clever :(. Ach
well.


But at least you took the heat that I would have gotten, as I was
going to suggest the same thing. :)
 
P

Paul Lalli

But at least you took the heat that I would have gotten, as I was
going to suggest the same thing. :)

I did the same thing too - I just tested it before I posted. :p

Paul Lalli
 
P

Peter J. Holzer

I just don't see the point of using a method that's only sometimes
valid as opposed to using one that's always valid.

There is no method which is always valid.

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top