Peter
Peter

Reputation: 131

Use sed/awk to replace text in multiple lines at once

I have a very large (~60MB) text file in which I want to replace specific block lines with a predefined text. The line number of every block (3 lines) start is known and they are stored in a file:

...
11
30
42
58
...

I know that I can use the following option in order to replace a block:

sed -i "Xs,(X+3)s/.*/REPLACEMENT/" filename.txt

However, executing this command in a for loop like:

for line in $(cat linenumbers.txt); do
  eline=$((${line}+3))
  sed -i "Xs,(X+3)s/.*/REPLACEMENT/" filename.txt
done

is very slow and takes a lot of time (> 10') and I have 100s of files in which I have to replace blocks. Is there any other way to instruct sed to do that in one pass?

Upvotes: 0

Views: 830

Answers (3)

potong
potong

Reputation: 58420

This might work for you (GNU sed):

sed 's/.*/&,+3cREPLACEMENT/' lineNumbersFile | sed -f - file

Convert the line numbers file into a sed script and run it against the data file.

Upvotes: 0

karakfa
karakfa

Reputation: 67507

awk to the rescue!

$ awk 'NR==FNR      {start[$1]; next} 
       FNR in start {c=3} 
       c&&c--       {print "replacement"; next}1' indices file

this is a one pass process, you can save the output into a new file and overwrite the original one if you want.

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 203522

Similar to @karakfas answer but a different interpretation of your requirements (hint: an actual example with input and output would have cleared up the confusion):

awk '
    NR==FNR      { start[$1]; next } 
    FNR in start { print "replacement"; c=3 } 
    c&&c--       { next }
    { print }
' indices file

Upvotes: 0

Related Questions