sed regex для сопоставления нескольких полей и значений, включая кавычки - PullRequest
4 голосов
/ 06 октября 2019

У меня есть (разделенный пробелами) входной файл со строками, такими как:

field1=value1 field2="value 2" field3='value 3' field4="value '4'" ...

Количество полей зависит от строки. Чтобы правильно обработать такой файл, я в идеале хотел бы sed его и получить какой-нибудь табличный вывод, такой как:

field1 (tab) value1 (tab) field2 (tab) value 2 (tab) field3 (tab) value 3 (tab) field4 (tab) value '4'

До сих пор я был с чем-то вроде sed "s/\([a-z][a-z]*\)=\(['\"]\{0,1\}\)\(..*?\)\2/\t\1\t\3/g" но слишком далеко от решения моей проблемы. Моя трудность заключается в том, чтобы правильно обрабатывать отсутствие или наличие разделителей (кавычек) для значений. Ради элегантности (или выродка ) я придерживаюсь sed, но также рассмотрю альтернативу awk.

Заранее благодарен за любую помощь,

Редактировать : Я шокирован, но @Jotne прав.

echo "field1=value1 field2=\"value 2\" field3='value 3' field4=\"value '4'\"" | sed "s/\([a-z][a-z]*\)=\(\([^ ][^ ]*\)\|'\([^'][^']*\)'\|\"\([^\"][^\"]*\)\"\)/\1\t\3\4\5\t/g"

не работает: field1 = value1 field2 = "value 2"field3 = 'value 3' field4 =" value '4' "`

Хотя следующее (идея состоит в том, чтобы разобрать файл audit.log) работает:

root@XXX:~# tail -n 2 /var/log/audit/audit.log 
type=CRED_DISP msg=audit(1570385821.075:670): pid=32605 uid=0 auid=0 ses=399 msg='op=PAM:setcred acct="root" exe="/usr/sbin/cron" hostname=? addr=? terminal=cron res=success'
type=USER_END msg=audit(1570385821.075:671): pid=32605 uid=0 auid=0 ses=399 msg='op=PAM:session_close acct="root" exe="/usr/sbin/cron" hostname=? addr=? terminal=cron res=success'
root@XXX:~# tail -n 2 /var/log/audit/audit.log | sed "s/\([a-z][a-z]*\)=\(\([^ ][^ ]*\)\|'\([^'][^']*\)'\|\"\([^\"][^\"]*\)\"\)/\1\t\3\4\5\t/g"
type    CRED_DISP    msg    audit(1570385821.075:670):   pid    32605    uid    0    auid   0    ses    399  msg    op=PAM:setcred acct="root" exe="/usr/sbin/cron" hostname=? addr=? terminal=cron res=success 
type    USER_END     msg    audit(1570385821.075:671):   pid    32605    uid    0    auid   0    ses    399  msg    op=PAM:session_close acct="root" exe="/usr/sbin/cron" hostname=? addr=? terminal=cron res=success   

Почему

1 Ответ

0 голосов
/ 07 октября 2019

Это может сработать для вас (GNU sed):

sed -E 's/ \<([^ =]+)=("[^"]*"|'\''[^'\'']*'\'')/\t\1\t\2/g;s/=/\t/' file

Первая замена заменяет все поля = и интервалы, кроме первого поля. Вторая замена исправляет первую.

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