Bash, модифицирующий текст между отмеченными строками

340
pesekvi

У меня есть файл с более чем 8000 строк. Файл разделен на разделы, каждый раздел помечен текстом, как ## C, ## T, ## N. Я должен изменить некоторые строки в файле. Я использовал команду SED, чтобы отметить строки между этими маркерами. Я новичок в Bash, поэтому я был бы признателен за помощь. Я должен изменить текст между этими маркерами

##C ##A - beginning marker (must be next row after ##C) text lines, some of them I have to modify text lines, some of them I have to modify ##B -end marker 

Пока у меня есть эта команда, чтобы пометить линии между маркерами

sed -e '/##A/,/##B/{}' file.txt 

Строки отформатированы так:

ZDMAD BELCH 0 0 25 26 30 50 

Моя цель - изменить некоторые столбцы в определенных строках. Например: если первый столбец ZDMAD, измените третий столбец на 15.

Я использовал этот решенный вопрос для моего дальнейшего прогресса

0

1 ответ на вопрос

0
Kamil Maciorowski

Поскольку вы знаете, как sedдействовать только между маркерами, ваша настоящая проблема в том, что вы пока не можете заставить его «изменить некоторые столбцы». Это может быть сложно, потому sedчто не знает о столбцах.

Например: если первый столбец ZDMAD, измените третий столбец на 15.

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

Это работает в моем Debian:

awk ' BEGIN { marked=0 markA="##A" markZ="##B" } $1==markZ  $1=="ZDMAD" && marked==1 {$3=15} $1==markA   ' file.txt 

Процедура:

  1. Установите полезные переменные в начале (т.е. только один раз); начать в "не отмеченном" состоянии.

Тогда для каждой записи:

  1. Если первое поле является маркером конца, перейдите в состояние «без метки».
  2. Если условие выполнено в «помеченном» состоянии, выполните работу.
  3. Если первое поле является начальным маркером, перейдите в «помеченное» состояние.
  4. Распечатать всю запись.

Обратите внимание, что процедура сначала проверяет маркер конца, выполняет задание и проверяет последний маркер. Дело в том, что он не должен манипулировать линиями маркера. В вашем примере case условие ( ZDMAD) не может соответствовать ни одной линии маркера, поэтому другая последовательность не будет проблемой; но в целом вы должны принять это во внимание.

Спасибо. Мне пришлось добавить некоторое сравнение регулярных выражений, чтобы убедиться, что строки с ## N и ## A перед текстом, который я изменяю. Но через некоторое время попыток это работает. Я супер новичок в awk или sed. Раньше я создавал только сценарии резервного копирования, в основном, они были частью Crontab. Так что еще раз спасибо за ваш ответ. :) pesekvi 5 лет назад 0