LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   SED and Replacing Specific occurrence or Range of Lines (https://www.linuxquestions.org/questions/linux-newbie-8/sed-and-replacing-specific-occurrence-or-range-of-lines-750155/)

bridrod 08-25-2009 12:42 PM

SED and Replacing Specific occurrence or Range of Lines
 
Created a new post because the question is different....

How would I replace entries from a file if I did not know the specific line, but knew it's the second occurrence in the file?

And how would I do it also if I only knew it's actually between a range of lines (i.e.: 155-190 lines)?

Any input is welcome!

Thanks,

-Rod

colucix 08-26-2009 05:10 AM

1. I don't know a reliable method to replace the second occurrence using sed. In sed you can add a numeric flag to the substitution command to replace the second occurrence of a pattern on the same line, but if the second occurrence is on another line I'd suggest to use awk instead:
Code:

awk '/pattern/{
  for (i = 1; i <= NF; i++){
    if ($i == "pattern")
      count++
    if (count == 2)
      sub("pattern","replacement",$i)
  }   
}1' file

this works in both cases where the second occurrence is on the same line of the first one or on another line.

2. To specify a range of lines in sed (for example from the 3rd to the 6th):
Code:

sed '3,6 s/pattern/replacement/' file

Kenhelm 08-26-2009 01:11 PM

This uses GNU sed to replace the second occurrence of a pattern in a file.
It first loads the entire file into the sed pattern space, so this method will fail if the file is too big to fit into the available memory.
Some non-GNU versions of sed have fixed limits on the size of the pattern space.
http://sed.sourceforge.net/sedfaq6.html#s6.6
Code:

sed ':a N;$!ba; s/pattern/replacement/2' infile > outfile

bridrod 08-26-2009 01:34 PM

Thanks for all the input! I will keep it saved and try it when I get a chance! you guys rock!

-Rod

pixellany 08-26-2009 03:54 PM

Code:

sed '/OLD/{:1 n;/OLD/{s/OLD/NEW/;:2 n;$!b2};b1}' filename > newfilename
I KNEW SED could do it!! Thanks to Kenhelm for this bit:
:2 n;$!b2
In my example, it's used to run thru the rest of the file without changing anything

What it does:
Looks for a line with "OLD"
....When found, it loops (#1)--getting the next line--till it finds another instance of "OLD"
........If found, it performs the substitution, then enters the "do nothing" loop (#2) to end of file
........If not, it falls thru to the end
....If not, it falls thru to the end


<<Edit: PS: The only advantage over Kenhelm's method is that it is maybe not so dependent on file size.>>

Kenhelm 08-26-2009 07:29 PM

pixellany, your solution doesn't cover the special case of the first and second 'OLD' both being on the same line; it needs two extra commands:-
Code:

sed '/OLD/{s/OLD/NEW/2;t2;:1 n;/OLD/{s/OLD/NEW/;:2 n;$!b2};b1}'
Your method does have the advantage of loading only one line at a time into the pattern space, which is useful for dealing with large files.

pixellany 08-26-2009 08:08 PM

touche!!!

bridrod 08-27-2009 09:59 AM

Quote:

Originally Posted by pixellany (Post 3658763)
Code:

sed '/OLD/{:1 n;/OLD/{s/OLD/NEW/;:2 n;$!b2};b1}' filename > newfilename
I KNEW SED could do it!! Thanks to Kenhelm for this bit:
:2 n;$!b2
In my example, it's used to run thru the rest of the file without changing anything

What it does:
Looks for a line with "OLD"
....When found, it loops (#1)--getting the next line--till it finds another instance of "OLD"
........If found, it performs the substitution, then enters the "do nothing" loop (#2) to end of file
........If not, it falls thru to the end
....If not, it falls thru to the end


<<Edit: PS: The only advantage over Kenhelm's method is that it is maybe not so dependent on file size.>>

You guys rock! I tested all the scripts provided and they all worked great!

I just have difficulties understanding the different options from this particular script line:

sed '/OLD/{s/OLD/NEW/2;t2;:1 n;/OLD/{s/OLD/NEW/;:2 n;$!b2};b1}'

The explanation for each "session" provided by pixellany I understood fine, but WHY they are structure the way shown above is confusing.

Would one of you mind explaining each option from the SED line so a newbie like me can understand it? I tried reading the manual but holy! Is it complicated!

TIA,

-Rod


All times are GMT -5. The time now is 06:23 AM.