Sed/Awk сохранить текст между шаблонами, если содержит строку
У меня проблема с почтой. Мне нужно получить все сообщения от 2 человек:somebody1@domain.com а также person@domain.com,
file:
From: somebody1@domain.com
to: person@domain.com
<body of the message1>
From: somebody2@domain.com
to: person@domain.com
<body of the message1>
From: somebody1@domain.com
to: person@domain.com
<body of the message1>
From: somebody3@domain.com
to: person@domain.com
<body of the message1>
From: somebody5@domain.com
to: person@domain.com
<body of the message1>
Я пытался использовать следующее sed:
sed -n "/From: [Ss]omebody1/,/From: /p" inputfile > test.txt
В результате я получил все письма от test.txt файл.
Вопрос в том, какой должна быть структура sed получать только письма между кем-то1 и человеком?
2 ответа
С sed:
sed -n '/^From: somebody1@domain.com/{h;n;/^to: person@domain.com/{H;g;p;:x;n;p;s/.//;tx}}' file
/^From: somebody1@domain.com/: первый поискFrom:адрес электронной почтыh;сохранить эту строку в пространстве удержания.n;загрузить следующую строку (to:линия).
/^to: person@domain.com/: поискto:адрес электронной почтыH;добавить эту строку в пространство удержания.g;скопируйте пространство удержания в пространство шаблона.p;распечатать шаблон пространства.:x;установить ярлык с именемx,n;загрузить следующую строку (тело письма)p;напечатайте эту строку.s/.//сделать замену в этой строке (просто заменить один символ)...tx... чтоtКоманда может проверить успешность этой замены (когда строка не пустая, как в конце тела письма). Если да, вернитесь к меткеxи повторять, пока не появится пустая строка, если не перейти к концу скрипта.
Выход:
From: somebody1@domain.com
to: person@domain.com
<body of the message1>
From: somebody1@domain.com
to: person@domain.com
<body of the message1>
With awk:
awk '/From: [Ss]omebody1/{flag=1;next} \
/to\: person1/ {if (flag>0) {flag=2; print; next} else {flag=0; next}} \
/From/{flag=0} {if (flag==2){print NR,flag, $0}} ' input.txt
/From: [Ss]omebody1/{flag=1;next} \Put a flag variable to 1 on match and skip the line./to\: person1/If the flag is 1 update it to 2 else reset it to 0./From/{flag=0}On match it reset the flag value.{if (flag==2){print NR, $0}}if flag is 2 it will print the linenumber and the line.
Изменить значение person1 to have different matches.
Input file used
From: somebody1@domain.com
to: person2@domain.com
<body of the message1>
From: somebody2@domain.com
to: person1@domain.com
<body of the message2>
From: somebody1@domain.com
to: person1@domain.com
<body of the message3>
From: somebody1@domain.com
to: person1@domain.com
<body of the message4>
From: somebody3@domain.com
to: person@domain.com
<body of the message5>