sed: вставлять строку после каждых N строк - PullRequest
23 голосов
/ 29 июля 2011

Я хочу вставить строку после каждых 30 строк в моем большом файле. Я использую mini-sed, который не поддерживает оператор диапазона ~ (тильда). Я ищу решение sed-only, пожалуйста.

Ответы [ 6 ]

43 голосов
/ 01 ноября 2012

Эта тема является еще одним примером того, как усложнять вещи. Это должно сделать это:

sed '0~30 s/$/string/g' < inputfile > outputfile

Каждые 30 строк «строка» вставляется в конце строки. Если вы хотите новую строку со словом «строка», просто используйте «\ n строка».

6 голосов
/ 30 июля 2011

Вставляет строку каждые 3 строки;

seq 1 10 | sed ': loop; n; n; a insert
n; b loop'

Производство

1
2
3
insert
4
5
6
insert
7
8
9
insert
10

скорректируйте количество команд n; перед командой a соответственно

2 голосов
/ 24 апреля 2017

Вставляет строку после каждых 3 строк.

[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] #
2 голосов
/ 11 ноября 2016

Использование

sed '1~30 i everyThirtyLine' file.dat

Это проверено в Cygwin.

2 голосов
/ 31 июля 2011

Начало редактирования

Для исходного решения ниже требуется столько памяти в пространстве удержания, сколько и размер N строк.Это лучшее решение, в котором вместо всех строк хранится '\n' вместо всех строк, что требует гораздо меньше памяти:

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

То же самое можно сделать с помощью команды i, которая менее известна, чем командаКоманда s:

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

Снова объясненная версия, которая может быть запущена с '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

Конец редактирования

следующий скрипт добавит '\nnew line' после каждых 5 строк.Если вы хотите делать это каждые 6 или 100 строк, просто измените '\{5\}' на '\{6\}' или '\{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

Это заслуживает некоторых пояснений, поэтому ниже приведена версия файла сценария с комментариями.Он должен быть запущен с '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
2 голосов
/ 29 июля 2011
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
...