-2

Want to add a new line in a file using perl script. I have tried but no luck

 if($correctedContents[$i] ~= /second line/){
 @data = $correctedContents[$i]
  push (@data, '\n TEST Line');

For example: add a "TEST Line" into a file whenever it find 'second line' line.

file1.txt,

first line
second line
third line

first line 
second line 
third line

.....

After added a new line expected output:

first line
second line
TEST Line
third line

first line 
second line 
TEST Line
third line

Thanks in Advance

Beginner
  • 77
  • 1
  • 9
  • using if condition i found the 'second line', then assigned to a array. finally i used push command to add a line but it was not worked – Beginner Dec 11 '17 at 12:44
  • Could you please go through the answers which you have received since [@dave cross](https://stackoverflow.com/a/47753759/4251338) mentioned already `Tie::File` module in his answer. There is a few samples available in search engine based on the modules. – ssr1012 Dec 11 '17 at 13:34

2 Answers2

2

You haven't really shown us enough of your code for us to be very much help. But, in particular, you haven't shown any code where you write the changed data back to an output file.

In general, tasks like this boil down to three stages:

  1. Read data from file.
  2. Update data in some way.
  3. Write changed data back to file.

One common approach is to have two filehandles open - one to your input file and another to a new output file. That makes it simple to process the file a line at a time.

while (<$input_fh>) {
  if (this is a line you need to change) {
    # make changes to line (which is in $_)
    # Perhaps print an extra line here.
  }
  print $output_fh $_;
}

Another approach (which trades speed for ease of use) is to use the Tie::File module (which is part of all Perl distributions since 5.8).

As always, the Perl FAQ is a good place for more information. In this case, you probably want to look at perlfaq5, which contains the question How do I change, delete, or insert a line in a file, or append to the beginning of a file?

Update: You already have one (slightly problematic) Tie::File-based solution. So here's mine:

#!/usr/bin/perl

use strict;
use warnings;

use Tie::File;

tie my @lines, 'Tie::File', 'somefile.txt'
  or die "Can't tie file: $!\n";

for (@lines) {
  $_ .= "\nTEST line" if $_ eq 'second line';
}
Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • i dont want to change the existing line. Need to add a new line – Beginner Dec 11 '17 at 13:19
  • dont want print the output in display, need to insert a line into a file – Beginner Dec 11 '17 at 13:20
  • @Beginner Dave showed you here to do exactly that. It seems that you need to perhaps start by [learning some perl](http://perl-begin.org/) and perhaps you would understand more what has been said here. – Gerhard Dec 11 '17 at 13:21
  • 2
    And if you took the time to read my answer and the document that I linked to, then you would realise that I have explained how to do everything you ask. If you have questions about my answer, then feel free to ask them. But don't just assume I haven't answered your question. – Dave Cross Dec 11 '17 at 13:22
  • @DaveCross Please check the comment from the OP in my answer – ssr1012 Dec 12 '17 at 13:28
  • we cant do without Tie::File ? – Beginner Dec 12 '17 at 14:36
  • @Beginner: I never said that. And I'm not sure where you got that idea from. Did you read the FAQ link I gave you? – Dave Cross Dec 12 '17 at 15:09
0

You may use Tie::File can get the output what you have expect

use Tie::File;

my $inputFile = "test.txt";

my @array;
tie @array, 'Tie::File', $inputFile or die "Error: Couldn't tie the \"$inputFile\" file: $!";
my $len = join "\n", @array;

if($len=~m/second line/i) {  $len=~s/second line/$&\nTEST Line/ig;  }

@array = split/\n/, $len;
untie @array;

Tie::File will replace the string in a same input file.

ssr1012
  • 2,573
  • 1
  • 18
  • 30
  • 1. Using `||` instead of `or` here might lead to precedence issues. 2. Using `join` and `split` seems a very strange approach. 3. You haven't added a line, you have overwritten it. – Dave Cross Dec 11 '17 at 13:38
  • @DaveCross: #1 will update in answer. #2. I don't know how to change instead of `join/split` using in code. #3. _Tie::File will replace the string in a same input file._ I have mentioned this. – ssr1012 Dec 11 '17 at 13:42
  • You could fix your solution by changing the substitution to: `s/second line/second line\nTEST line/`. Because currently, your answer doesn't do what @beginner asked for. I have no idea why he accepted it. – Dave Cross Dec 11 '17 at 13:48
  • Update your question please _for my case_ – ssr1012 Dec 12 '17 at 06:44
  • @ssr1012: His question already explains why your solution does work. He wants a new line inserted after the lines that match `/second line/`. Your code replaces the line, it doesn't add a new line. And my comment above explains how to fix that. – Dave Cross Dec 12 '17 at 08:41
  • @Beginner: If this answer doesn't work for you, why have you accepted it? – Dave Cross Dec 12 '17 at 08:41
  • @Beginner: Please accept the davecross answers below. – ssr1012 Dec 12 '17 at 10:59
  • suppose i want to search the 'second' word in a file if it is not there add 'second line' after the 'first line'. how we can do that – Beginner Dec 12 '17 at 13:23
  • @Beginner: If you have new requirements to add, then please don't add them as comments. It's best to raise a new question. – Dave Cross Dec 12 '17 at 13:32
  • If raise some people dont like me then they are doing downvote for that – Beginner Dec 12 '17 at 13:43
  • 1
    @Beginner: People aren't downvoting your questions because they don't like you. People are downvoting your questions because your questions are vague and badly-explained. Luckily, it's pretty easy to fix that. – Dave Cross Dec 12 '17 at 13:46
  • i have altered this questions. can you give some sample code of it – Beginner Dec 12 '17 at 13:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/161028/discussion-between-beginner-and-dave-cross). – Beginner Dec 12 '17 at 13:52