У меня есть несколько файлов, в которых мне нужно обрезать только строки, которые находятся между шаблоном @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