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

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

У меня есть несколько файлов, в которых мне нужно обрезать только строки, которые находятся между шаблоном @TEST и enabled="true">. При совпадении строка между @TESTи enabled="true">должна быть длиной всего 50 символов. Все остальные строки следует оставить нетронутыми.

Пример:

@TEST-TC_0010 @TEST Убедитесь, что сервер учета RADIUS не должен отправлять сообщение Accounting-Response при получении пакета Accounting-Request от клиента RADIUS" enabled="true">

Мне нужно изменить строку выше, как показано ниже.

@TEST-TC_0010@ТЕСТУбедитесь, что сервер учета RADIUS не долженвключено="истина">

решение1

В этом случае вы можете использовать grep с обходными путями Perl.

grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile

Выражение «(?<=)» отмечает точку, в которой начнется совпадение, а выражение «(?=)» — точку, в которой совпадение закончится.

«.*» сообщает grep, что нужно вернуть все данные между начальной и конечной точками.

Используя ваши тестовые входные данные, строка выше возвращает 157 символов.

$ echo "Verify that the RADIUS accounting server should not send the Accounting-Response Message on Receiving the Accounting-Request Packet from the RADIUS Client" | wc -m
157

Если вы хотите еще больше сократить текст до первых 50 символов, вы можете использовать команду cut.

$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50
Verify that the RADIUS accounting server should no

Если вы хотите сохранить результаты в файл, то вам нужно перенаправить вывод в другой файл. Вы можете использовать что-то вроде следующего...

$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50 >> outputfile

Я бы не рекомендовал перезаписывать входной файл, поскольку в какой-то момент вам может понадобиться использовать исходные данные.

Поэтому, если вам нужно сохранить все остальные записи в файле и обрезать только те строки, в которых enabled="true", нам нужно сменить инструменты на awk.

$ awk  -F'@TEST' '{if (/true/) print substr($3,2,50); else print $0}' inputfile >> outputfile

Этот oneliner выведет без изменений каждую строку, которая не соответствует true. Если true соответствует, то строка будет усечена до 50 символов. Опять же, я не рекомендую перезаписывать исходные данные, поэтому результаты передаются в выходной файл.

На основе последних правок, внесенных в вопрос автором, я изменил однострочник awk, чтобы воспроизвести вывод, предоставленный Beginner. Он упомянул в своем комментарии, что awk не работает. Пока автор не предоставит больше подробностей о том, почему awk не работает, при использовании awk 4.1.3 в Ubuntu 16.04 следующая строка вернет результаты, которые он подробно описал до сих пор.

awk  -F'@TEST' '{if (/true/) print "@TEST"$2,"@TEST",substr($3,2,50),"enabled=\"true\">"; else print $0}' inputfile >> outputfile

Связанный контент