Для ваших образцов данных:
sed -i '/\([^|]*|\)\{7\}/{s/\([^|]*|\)/"\1/4;s/\(|[^|]*\)/"\1/6}' inputfile
Для ваших реальных данных:
sed -i '/\([^|]*|\)\{17\}/{s/\([^|]*|\)/"\1/14;s/\(|[^|]*\)/"\1/16}' inputfile
Редактировать:
(я добавил парупропущенных фигурных скобок в каждом примере, поэтому вторая команда s
(фактически обе) работает только при совпадении адреса. Я также удалил -n
и p
. Удаление p
устраняет дублирование. Извините за ошибки.)
Часть перед командой s
называется "адресом".Он выбирает только те строки, которые имеют 7 (или 17) символов канала, что исключает использование команды s
для строк с другим количеством символов канала.
//
- Разделители дляадрес \(\)
- групповые скобки (экранированные) [^|]*
- ноль или более (*
) непотоковых (^|
) символов ([]
- символсписок разделителей) |
- и интересующий нас символ канала \{7\}
- повторить группу семь раз {command; command}
- эти скобки разделяютблок команд, который будет выполняться при сопоставлении адреса - вместе адрес и фигурные скобки действуют как оператор if
и связанный с ним блок
, так что этот адрес соответствует строкам, которые имеют семь группноль или более непутевых символов, за каждым из которых следует символ канала.
Тогда первая команда s
говорит о замене 4-го (или 14-го) символа канала и его предшествующих символов, не являющихся каналами, кавычкой, за которой следуют соответствующие символы.
Точка с запятой является разделителем команд.Некоторые версии sed
требуют, чтобы вместо точек с запятой вы использовали форму `sed -e 'command' -e 'command' для однокомпонентных сценариев с несколькими командами.
Кстати, s
это команда, а не часть регулярного выражения.Часть между начальной парой слешей в командах выше и часть между начальной парой слешей в команде s///
являются регулярными выражениями.
Пожалуйста, дайте мне знать, если у вас есть дополнительные вопросы.Вторая команда s
ищет 6-й (или 16-й) символ канала и ноль или более непузырьков, следующих за ним, и заменяет его на себя (совпавшие символы) и кавычку.