I want to insert a string after every 30 lines in my large file. I'm using mini-sed, which doesn't support ~ (tilde) range operator. I'm looking for sed-only solution please.
-
3I'm sure you have your reasons, but it's hard to not suggest `awk` here. – Eric Wilson Jul 29 '11 at 15:07
-
Actually i'm not sure he has a reason. – Karoly Horvath Jul 31 '11 at 16:31
-
1@KarolyHorvath http://www.exactcode.com/site/open_source/minised/ I'm sure he has a lot of reasons – user1207217 Feb 27 '13 at 19:46
-
@user1207217: enlighten me.. – Karoly Horvath Feb 27 '13 at 21:34
6 Answers
This thread is another example of how to over complicate things. This should do it:
sed '0~30 s/$/string/g' < inputfile > outputfile
Every 30 lines "string" is inserted at the end of the line. If you want a new line with the word "string" just use "\n string".

- 7,497
- 2
- 27
- 46
-
1'thread' is never the right word for a Stack Overflow page. I take your point, but you are talking about 'the other answers to this question'. :-) – Martijn Pieters Nov 01 '12 at 17:38
-
14Although this was what I wanted, the asker specifically asked for solutions not using tilde. – user1207217 Feb 27 '13 at 19:45
-
This did not work: sed '0~5000 s/$/\n commit;/g' < batch.sql > batch-commit.sql sed: 1: "0~5000 s/$/\n commit;/g": invalid command code ~ – Janakiram Apr 30 '18 at 04:07
-
Probably way too late for you but I think the issue is you need to delimit the semicolon - sed '0~5000 s/$/\n commit\;/g' – Winter Apr 29 '20 at 20:03
Use
sed '1~30 i everyThirtyLine' file.dat
This is tested in Cygwin.

- 9,623
- 5
- 30
- 36

- 153
- 2
- 9
This inserts a line every 3 lines;
seq 1 10 | sed ': loop; n; n; a insert
n; b loop'
Producing
1
2
3
insert
4
5
6
insert
7
8
9
insert
10
adjust the number of n;
commands before the a
command accordingly

- 238,783
- 38
- 220
- 352
This inserts a line after every 3 lines.
[STEP 101] # cat insert.sed
# add one more 'x' into the hold space
x
s/^/x/
t reset_t_cond
: reset_t_cond
# check if there are 3 'x' chars now
s/x\{3\}//
x
t insert
b
: insert
a\
INSERT HERE
[STEP 102] # seq 10 | sed -f insert.sed
1
2
3
INSERT HERE
4
5
6
INSERT HERE
7
8
9
INSERT HERE
10
[STEP 103] #

- 19,215
- 5
- 38
- 56
sed 'n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;s/$/\
string/' filename

- 96,650
- 16
- 149
- 150
-
Hi, Thanks. Is there a shorter way. To insert every 100 lines, I want to avoid specifying 'n' 100 times. – user868923 Jul 30 '11 at 08:09
-
2@user868923, short answer: no, at that point you're really using the wrong tool. You *could* use sed to *construct* that string of n's and then run it, but it would be a sed command so arcane that it would really only be good for impressing other wizards. Hmm... – Beta Jul 30 '11 at 19:46
Begin Edit
The initial solution bellow needs as much memory in the hold space as the size of the N lines. This is a better solution that only keeps '\n'
in the hold space instead of all the lines, needing much less memory:
sed -e 'p;G;s/[^\n]//g;t next;:next;s/^\n\{5\}$//;t insert;h;d;:insert;x;s/^.*$/new line/' your_large_file
The same can be done using the i command that is less known than the s command:
sed -e 'p;G;s/[^\n]//g;t next;:next;s/^\n\{5\}$//;t insert;h;d;:insert;x;i \
new line
d' your_large_file
Again, the explained version that can be run with 'sed -f script your_large_file'
:
# Whatever happen afterward, the current line need to be printed.
p
# Append the hold space, that contains as much \n as the number of lines read since the text has been added.
G
# Keeps only the \n in the pattern space.
s/[^\n]//g
# The 't next' bellow is needed so the 't insert' will not take into account the s command above.
t next
:next
# If we have exaclty 5 \n in the patern space, empty the hold space and insert the text, else save the pattern space for next cycle.
# In both cases, end the current cycle without printing the pattern space.
s/^\n\{3\}$//
t insert
h
d
:insert
x
i \
new line
d
End Edit
The following script will add '\nnew line'
after each 5 lines. If you want to do it every 6 or 100 lines, just change the '\{5\}'
by '\{6\}'
or '\{100\}'
.
sed -n -e 'H;g;s/[^\n]//g;t next;:next;s/^\n\{5\}$//;t insert;$ {x;s/^\n//;p};b;:insert;x;s/$/\nnew line/;s/^\n//;p' your_large_file
This deserves some explanations, so bellow is a commented script file version . It must be run with 'sed -n -f script your_large_file'
.
H
g
# Now, the pattern and hold space contain what has been read so far with an extra \n at the beginning.
s/[^\n]//g
# Now, the pattern space only contains \n, the hold space is unmodified.
# The 't next' bellow is needed so the 't insert' will not take into account the s command above.
t next
:next
# If we have exactly 5 new lines in the pattern space, the hold space is printed without the \n at the beginning and with the text to added after 5 lines at its end.
s/^\n\{5\}$//
t insert
# If not 5 \n and at the last line, the hold space must be printed without the \n at its beginning.
$ {x;s/^\n//;p}
b
:insert
x
# Now the hold space is empty and ready to receive new lines as the pattern space has been emptied by the 2 s commands above.
s/$/\nnew line/
s/^\n//
p

- 16,077
- 4
- 26
- 34
-
1Take a look at [my solution](http://stackoverflow.com/a/43579719/900078) which is simpler. :) – pynexj Apr 24 '17 at 04:19