найти строки в файле и очистить данные, заключенные в теги

Используйте

:msg, contains, "3-6.2.4: reset full" ~

Тильда будет отбрасывать сообщения, содержащие строку «3 -6.2.4 :полный сброс».

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

if ($programname == 'kernel:') and ($msg contains "reset full-speed") then { *.* ~ }
& stop
1
03.04.2021, 21:03
2 ответа

Если это правильно структурированный язык, такой как XML, вам действительно следует использовать вместо этого специальные анализаторы (рассмотрим xmlstarlet, например ). Тем не менее, пока ваши файлы достаточно малы, чтобы поместиться в памяти, и предполагая, что, как вы говорите в комментариях, у вас будет только новая строка в поле в тех случаях, когда поле пусто, поэтому замена не требуется, вы мог бы просто сделать это:

$ sed '/<nr>/{s/[. -]*//g}' file
<id>474488</id>
<name>Shawn</name>
<nr>143385</nr>

<id>474490</id>
<name>Bob</name>
<nr>274388</nr>#thisisthelineofinterest

<id>474568</id>
<name>Jim</name>
<nr>
</nr>
....

Для более сложных случаев и если бы я не мог использовать подходящий синтаксический анализатор, я бы выбрал perl:

$ perl -nle '$k=1 if /<nr>/; if($k){s/[. -]//g}; $k=0 if /<\/nr>/; print' file
<id>474488</id>
<name>Shawn</name>
<nr>143385</nr>

<id>474490</id>
<name>Bob</name>
<nr>274388</nr>#thisisthelineofinterest

<id>474568</id>
<name>Jim</name>
<nr>
</nr>
....

Но учтите, что описанное выше не удастся, если в одной строке может быть несколько тегов, например:

<nr>143385</nr><name>Shawn - Mary</name>

В таких случаях -также будет удален из значения <name>. Именно в таком крайнем случае лучше всего использовать парсер.

Для вариантов perlи sedвы можете использовать -iдля редактирования файла на месте:

sed -i '/<nr>/{s/[. -]*//g}' file
perl -i -nle '$k=1 if /<nr>/; if($k){s/[. -]//g}; $k=0 if /<\/nr>/; print' file
0
28.04.2021, 22:54

Похоже, это фрагмент XML. Добавив закрывающий элемент <root/>, чтобы у нас был ниже XML, мы можем затем использовать инструмент редактирования XML,

xmlstarlet ed -u '//nr' -x 'translate(text(), "-.", "")' file.xml
<?xml version="1.0"?>
<root>
  <id>474488</id>
  <name>Shawn</name>
  <nr>143385</nr>
  <id>474490</id>
  <name>Bob</name>
  <nr>274388</nr>
  <id>474568</id>
  <name>Jim</name>
  <nr>
</nr>
</root>

Важным моментом здесь является функция XPath translate(). По действию она аналогична команде UNIX/Linux trтем, что заменяет символы из одной строки символами из другой (первый параметр — это значение, с которым нужно работать ).

Я использовал nrкак крючок для работы. Путь к элементу может быть более точным, если требуется (в моем примере /root/nrтакже можно использовать ).

Очень немногие инструменты фильтрации действительно работают с файлами в -месте. Они пишут временный файл, а затем используют его для замены оригинала. В этом случае мы должны реализовать это сами

xmlstarlet... file.xml >file.xml.tmp && mv -f file.xml.tmp file.xml
2
28.04.2021, 22:54

Теги

Похожие вопросы