Reputation: 131
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
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
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
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