2016-09-13 1 views
0

Я хочу добавить символ «>>» в конце 1-й строки, а затем 5-й и так далее. 1,5,9,13,17, .... Я искал в Интернете и проходил ниже статьи, но я не могу этого добиться. Пожалуйста помоги.Как я могу добавить любую строку в конце строки и продолжать делать это после определенного количества строк?

How can I append text below the specific number of lines in sed?

retentive 
good at remembering 
The child was very sharp, and her memory was extremely retentive. 
— Rowlands, Effie Adelaide 

unconscionable 
greatly exceeding bounds of reason or moderation 
For generations in the New York City public schools, this has become the norm with devastating consequences rooted in unconscionable levels of student failure. 
— New York Times (Nov 4, 2011) 

Выход должен быть как-

retentive >> 
good at remembering 
The child was very sharp, and her memory was extremely retentive. 
— Rowlands, Effie Adelaide 

unconscionable >> 
greatly exceeding bounds of reason or moderation 
For generations in the New York City public schools, this has become the norm with devastating consequences rooted in unconscionable levels of student failure. 
— New York Times (Nov 4, 2011) 
+0

Вы уверены, что хотите линии 1,5,9, ...? Ваш пример, похоже, нуждается в 1,6,11,16 ... – redneb

ответ

1

Вы можете сделать это с awk:

awk '{if ((NR-1) % 5) {print $0} else {print $0 " >>"}}' 

Мы проверяем номер строки минус 1 кратно 5 и если это мы выводим строку, за которой следует >>, oth Мы просто выводим линию.

Примечание: Приведенный выше код выводит суффикс каждые 5 строк, потому что это то, что необходимо для вашего примера для работы.

+0

Вы рок, спасибо @redneb, он отлично работает. – eiffeldreams

0

Вы можете сделать это несколькими способами. sed выглядит странно, когда дело доходит до выбора линий, но это выполнимо. Например .:

СЭД:

sed -i -e 's/$/ >>/;n;n;n;n' file 

Вы можете сделать это также, как Perl Однострочник:

perl -pi.bak -e 's/(.*)/$1 >>/ if not (($. - 1) % 5)' file 
0

Вы думаете об этом неправильно. Вы должны добавить в конец первой строки каждого абзаца, не волнуйтесь о том, сколько строк там будет в любом данном пункте. Это просто:

$ awk -v RS= -v ORS='\n\n' '{sub(/\n/," >>&")}1' file 
retentive >> 
good at remembering 
The child was very sharp, and her memory was extremely retentive. 
— Rowlands, Effie Adelaide 

unconscionable >> 
greatly exceeding bounds of reason or moderation 
For generations in the New York City public schools, this has become the norm with devastating consequences rooted in unconscionable levels of student failure. 
— New York Times (Nov 4, 2011) 
+0

Похоже, что данные не содержат свободных абзацев. Похоже, что третий элемент в каждой записи - это цитата, и эта цитата развернута, чтобы быть одной строкой, чтобы придерживаться четырехстрочного формата: * word *, * short definition *, * example quote *, * source *, ' пустая строка'. – Kaz

0

Это может работать для вас (GNU СЭД):

sed -i '1~4s/$/ >>/' file 
0

Вот нечисловое путь в Awk. Это работает, если у нас есть Awk, который поддерживает переменную RS длиной более одного символа. Мы разбиваем данные на записи на основе разделения пустой строки: "\n\n". Внутри этих записей мы прерываем поля на линиях новой строки. Таким образом $1 слово, $2 является определением, $3 является котировкой и $4 является источником:

awk 'BEGIN {OFS=FS="\n";ORS=RS="\n\n"} $1=$1" >>"' 

Мы используем одни и те же выходные разделители в качестве входных сепараторов. Наш единственный шаблон/шаг действия - это отредактировать $1 так, чтобы на нем было >>. Действие по умолчанию - { print }, что и мы хотим: напечатайте каждую запись. Поэтому мы можем опустить это.

Сокращенное: Инициализация RS от FS.

awk 'BEGIN {OFS=FS="\n";ORS=RS=FS FS} $1=$1" >>"' 

Это красиво выразительно: в нем используются два последовательных разделителя полей для разделения записей.

Что делать, если мы используем флаг, первоначально сброшенный, который сбрасывается на каждой пустой строке? Это решение по-прежнему не зависит от жестко закодированного номера, а просто для разделения пустой строки. Правило, пожары на первой линии, потому что C оценивает до нуля, а затем после каждой пустой строки, потому что мы сбрасываем C нулю:

awk 'C++?1:$0=$0" >>";!NF{C=0}' 

Сокращенный вариант принятого решения Awk:

awk '(NR-1)%5?1:$0=$0" >>"' 

Мы можем использовать тернарное условное выражение cond ? then : else как шаблон, оставив действие пустым, чтобы оно по умолчанию было {print}, что, конечно же, означает {print $0}. Если нулевой номер записи равен , а не, сравнимый с 0, по модулю 5, то мы создаем 1, чтобы вызвать действие печати. В противном случае мы оцениваем `$ 0 = $ 0" >> ", чтобы добавить требуемый суффикс в запись. Результатом этого выражения является также логическое значение true, которое запускает действие печати.

сбрить еще один символ: мы не должны вычесть 1 из NR, а затем тест для сравнения нулю. В основном, когда 1 на основе номера записи конгруэнтно 1, по модулю 5, то мы хотим, чтобы добавить >> суффикс:

awk 'NR%5==1?$0=$0" >>":1' 

Хотя мы должны добавить ==1 (+3 символов), мы победим, потому что мы можем упасть две круглые скобки и -1 (-4 символа).

Мы можем сделать лучше (с некоторыми допущениями): Вместо редактирования $0, что мы можем сделать, это создать второе поле, содержащее >> путем присвоения параметру $2. Неявное print действие напечатает это, офсет пробелом:

awk 'NR%5==1?$2=">>":1' 

Но это работает только, когда линия определение содержит одно слово. Если какое-либо из слов в этом словаре является составными существительными (разделенное пробелом, а не переносом), это терпит неудачу. Если попытаться восстановить этот недостаток, мы, к сожалению, вернулись к той же длине:

awk 'NR%5==1?$++NF=">>":1' 

Незначительное изменение на подходе: Вместо того, чтобы пытаться лавировать >> на запись или последнего поля, почему не мы условно устанавливаем >>\n как ORS, разделитель выходной записи?

awk 'ORS=(NR%5==1?" >>\n":"\n")' 

Не the tersest, но стоит упомянуть. Он показывает, как мы можем динамически играть с некоторыми из этих переменных от записи к записи.

Различные способы тестирования NR == 1 (mod 5): а именно, regexp!

awk 'NR~/[16]$/?$0=$0" >>":1' 

Опять же, не tersest, но, кажется, стоит упомянуть. Мы можем рассматривать NR как строку, представляющую целое число в виде десятичных цифр.Если он заканчивается 1 или 6, то он сравним с 1, mod 5. Очевидно, что не легко модифицировать другие модули, не говоря уже об отвратительном вычислении.

0

Там есть еще пара:

$ awk 'NR%5==1 && sub(/$/,">>>") || 1 ' foo

$ awk '$0=$0(NR%5==1?">>>":"")' foo

Смежные вопросы