Как вставить шаблон каждые n символов с вводом, которые могут иметь новые строки? - PullRequest
2 голосов
/ 25 октября 2019

Я пытаюсь использовать sed для вставки шаблона в файл каждые 2000 символов. Я использую эту команду sed, но она не работает, если файл содержит несколько строк, потому что счетчик сбрасывается в каждой новой строке.

Pattern: ' || '

sed "s/.\{2000\}/&'\n || '/g" file

Как мне заставить эту команду работать с вводом, который может иметь или не иметь новые строки? Я в порядке с решением без sed.

Вот пример, вставляющий шаблон каждые 4 символа вместо 2000.

Пример ввода:

aaaaaa
bbbbbb

ПримерВывод:

aaaa'
 || 'aa
b'
 || 'bbbb'
 || 'b
  1. Подсчет 4 символов (4 знака), вставка шаблона.
  2. Подсчет 4 символов (2 знака, символ новой строки и 1 b), вставка шаблона.
  3. Подсчитать 4 символа (4 б), вставить шаблон.
  4. Остался только 1 символ (1 б)

Спасибо.

Ответы [ 6 ]

3 голосов
/ 25 октября 2019

С GNU awk для RS с несколькими символами и считыванием только 4 символов в память за раз (в отличие от чтения всего файла в память одновременно, как того требуют некоторые другие решения):

$ awk -v RS='.{4}' '{printf "%s", (RT=="" ? $0 : RT "\047\n || \047")}' file
aaaa'
 || 'aa
b'
 || 'bbbb'
 || 'b
3 голосов
/ 25 октября 2019

perl -0777pe "s/(.{2000})/\$1'\n || '/gs" file

  • -0777 для обработки всего файла одной строкой
  • \$1, чтобы разрешить ссылку для захвата группы без оболочки, что делает его пустым, потому что у меня естьчтобы использовать двойные кавычки
  • s///gs использует g для повторения более одного раза и s, чтобы .{4} мог переносить символы новой строки.
$ printf "aaaaaa\nbbbbbb\n" |  perl -0777pe "s/(.{4})/\$1'\n || '/gs"
aaaa'
 || 'aa
b'
 || 'bbbb'
 || 'b
1 голос
/ 25 октября 2019

Будет работать следующее решение sed (с использованием четырех символов вместо 2000):

  sed "H;1h;\$!d;x;s/.\{4\}/&'\n || '/g"

Объяснение:

В bash,нам нужно экранировать знак доллара, \$, потому что, поскольку шаблон замены содержит одинарные кавычки, проще использовать двойные кавычки для включения строки sed.

Редактировать: КакПримечание Эда Мортона в комментарии, вместо использования двойных кавычек и экранирования $, альтернативой является использование одинарных кавычек и замена каждой встроенной одинарной кавычки ' на '\'', чтобы получить:

  sed 'H;1h;$!d;x;s/.\{4\}/&'\''\n || '\''/g'
1 голос
/ 25 октября 2019

Вот общий подход, в котором мы можем указать количество символов, после которого вы хотите вставить строку. Использование функций GNU awk RS, FS, gsub. Протестировано с GNU awk и только с предоставленными сэмплами. (Хорошо, я только что проверил, чтобы вставить НОВЫЙ символ после 5 символов, и это работало довольно хорошо :))

awk -v noc="4" -v char="\047\n || \047" -v RS="" -v FS="\n" '{num=num==noc?(noc-1):noc;gsub(".{"num"}","&" char)} 1' Input_file

Добавлениеформа решения не с одним вкладышем:

awk -v noc="4" -v char="\047\n || \047" -v RS="" -v FS="\n" '
{
  num=num==noc?(noc-1):noc
  gsub(".{"num"}","&" char)
}
1
'  Input_file

Вывод будет следующим:

aaaa'
 || 'aa
b'
 || 'bbbb'
 || 'b


Объяснение вышеприведенного кода: Добавление полного объяснения вышеприведенного кода.

awk -v noc="4" -v char="\047\n || \047" -v RS="" -v FS="\n" '  ##Mentioning noc=4 for number of characters after which we want to insert new character\
                                                               ## , mentioning char variable with value which OP wants to insert. \
                                                               ##  Making RS NULL here, making FS as new line here for all lines of Input_file
{
  num=num==noc?(noc-1):noc                                     ##Creating variable num whose value is noc-1 when it is 4 and 4 when it is NOT 4.
  gsub(".{"num"}","&" char)                                    ##Using gsub function to give number of characters which need to be substitutes with new char here.
}
1                                                              ##Mentioning 1 will print edited/non-edited line of Input_file.
'  Input_file                                                  ##Mentioning Input_file name here.
1 голос
/ 25 октября 2019

Это gnu awk может сделать:

echo "abcdefghijkl" | awk -v FS= -v OFS= '{for (i=1;i<=NF;i++) if (i>1 && i%3==1)  $i="\n ||"$i}1'
abc
 ||def
 ||ghi
 ||jkl

Для вашего файла, с каждыми 1000 символами.

awk -v FS= -v OFS= '{for (i=1;i<=NF;i++) if (i>1 && i%1000==1)  $i="\n ||"$i}1' file

Обновленное решение:

awk -v FS= -v OFS= '{for (i=1;i<=NF;i++) if (i>1 && i%4==1)  $i="\x27\\n || \x27"$i;printf "%s\x27\\n || \x27",$0} END {print ""}' file
aaaa'\n || 'aa'\n || 'bbbb'\n || 'bb'\n || '
0 голосов
/ 25 октября 2019

Существует специальная команда Linux для разделения файлов по заданным параметрам.

Подробнее о csplit команда здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...