Intereting Posts
скрипт bash, определяющий последнюю переменную пути Не удалять или перемещать в корзину в контекстном меню в некоторых каталогах (gnome) gcc создает ошибочный «Нет такого файла или каталога» под Cygwin Потеря данных через ttyACM *, когда для передачи данных используется команда ‘cat’ Окружение другого пользователя в дочернем процессе Что такое «магические аргументы» в системном вызове Linux reboot? Как получить информацию о моих виртуальных рабочих столах через командную строку? работающее ядро ​​на QEMU Как найти файлы, которые были созданы / изменены / доступны перед перезагрузкой? Ошибка при экспорте результата действительной команды в качестве переменной bash как просматривать журналы ошибок php и сервера? xentop дает статическую информацию об использовании памяти Системный контейнер systemd-nspawn непригоден, потому что я не могу установить пароль root раздражающее сообщение «Соединение X11 отклонено из-за неправильной аутентификации», в то время как нет никакой проблемы вообще Объединить аргумент xargs с некоторым текстом

Заменить строку перед определенной строкой

У меня есть один файл, как:

ID_SOUR_CALENDAR BIGINT NOT NULL DEFAULT 0 COMPRESS 0 , UNIQUE PRIMARY INDEX ( CALENDAR_DATE ); ID , ID_SOUR , PRIMARY INDEX ( CALENDAR_DATE ); 

Я хочу заменить ‘,’ на ‘)’ в строке непосредственно перед строкой, содержащей PRIMARY.

Результат должен быть:

 ID_SOUR_CALENDAR BIGINT NOT NULL DEFAULT 0 COMPRESS 0 ) UNIQUE PRIMARY INDEX ( CALENDAR_DATE ); ID , ID_SOUR ) PRIMARY INDEX ( CALENDAR_DATE ); 

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

 sed 'N;s/,\(\s*\n.*PRIMARY\)/)\1/;P;D' file ID_SOUR_CALENDAR BIGINT NOT NULL DEFAULT 0 COMPRESS 0 ) UNIQUE PRIMARY INDEX ( CALENDAR_DATE ); ID , ID_SOUR ) PRIMARY INDEX ( CALENDAR_DATE ); 
  • N Прочитайте / добавьте следующую строку ввода в пространство шаблона.
  • P Печать до первой встроенной новой строки текущего пространства шаблона.
  • D Удалить до первой встроенной новой строки в пространстве шаблона. Начните следующий цикл, но пропустите чтение из входных данных, если в пространстве шаблона еще есть данные.

Попробуйте перевернуть файл, заменив строку в строке после PRIMARY, затем переверните файл:

 tac file | sed '/PRIMARY/ {n; s/,$/)/}' | tac 

попробуй это,

 perl -0777 -pe 's/,([^\n,]*\n[^\n]*PRIMARY)/)$1/g' 

Это заменит последний , с ) в строках перед любой строкой, включая PRIMARY .

объяснение

  • perl -0777 весь файл (читается одной строкой)
  • s/search_pattern/replacement/g шаблон поиска на глобальный заменитель

Если вы используете ed а не sed вы можете использовать адрес регулярного выражения с отрицательным смещением:

 g/PRIMARY/-1 s/,$/)/ 

Ex.

 $ printf 'g/PRIMARY/-1 s/,$/)/\n,p\nq\n' | ed -s file ID_SOUR_CALENDAR BIGINT NOT NULL DEFAULT 0 COMPRESS 0 ) UNIQUE PRIMARY INDEX ( CALENDAR_DATE ); ID , ID_SOUR ) PRIMARY INDEX ( CALENDAR_DATE ); 

или (для редактирования на месте)

 printf 'g/PRIMARY/-1 s/,$/)/\nwq\n' | ed -s file 

Замена будет соответствовать ВСЕМ экземплярам /PRIMARY/ – если вы хотите заменить только первый, удалите модификатор g .

С POSIXly sed вы можете делать следующее:

 sed -e ' /PRIMARY/!{x;1!p;d;} x;s/,/)/;$G ' input-file.txt 

Выход:

 ID_SOUR_CALENDAR BIGINT NOT NULL DEFAULT 0 COMPRESS 0 ) UNIQUE PRIMARY INDEX ( CALENDAR_DATE ); ID , ID_SOUR ) PRIMARY INDEX ( CALENDAR_DATE ); 

За работой:

  • Для строк, не являющихся первичными, мы сохраняем строку и печатаем ту, которую сохранили в трюме.
  • А для ПЕРВИЧНОГО мы извлекаем предыдущее и осуществляем преобразование.