Этим вопросом является изменение того, Как делают меня grep для нескольких шаблонов на нескольких строках?
Это - демонстрационный текст где строки, содержащие "reqId: regexpat" или "reqCompleted: regexpat" должен быть подобран в парах, где 'regexpat' уникален, на самом деле это может быть UUID.
2016-09-27 GET /some/uri - reqId: 000-pat1-bgr, more text
2016-09-27 GET /some/uri - reqId: 0.215487, your favourite song
2016-09-27 irrelevant message
2016-09-27 ignored record
2016-09-27 reqCompleted: 999-xxx-vvv, ignore this
2016-09-27 reqCompleted: 0.215487, more characters
2016-09-27 reqCompleted: 000-pat1-bgr, more characters
2016-09-27 another lost message
Ожидаемый результат должен быть
2016-09-27 GET /some/uri - reqId: 000-pat1-bgr, more text
2016-09-27 GET /some/uri - reqId: 0.215487, your favourite song
2016-09-27 reqCompleted: 0.215487, more characters
2016-09-27 reqCompleted: 000-pat1-bgr, more characters
000-pat1-bgr и 0.215487 являются уникальными идентификаторами. Я попробовал grep поддержкой perl-regex
grep --null-data --only-matching --perl-regex '(?s)^\N+ RequestId:\1, \N+$\n(?:.*)^\N+ reqCompleted: ([a-z0-9\.-]+), .\N+$\n'
Но это - то, что я получаю
2016-09-27 GET /some/uri - reqId: 000-pat1-bgr, more text
2016-09-27 GET /some/uri - reqId: 0.215487, your favourite song
2016-09-27 irrelevant message
2016-09-27 ignored record
2016-09-27 reqCompleted: 999-xxx-vvv, ignore this
2016-09-27 reqCompleted: 0.215487, more characters
2016-09-27 reqCompleted: 000-pat1-bgr, more characters
Действительно ли возможно достигнуть этого с одним лайнером grep команда?
другой awk способ сохранить порядок строки с тех пор использования grep
awk -F"[:,]" '/reqCompleted/ || /reqId/{
dupsIDs[$(NF-1)]++
}END{
for (x in dupsIDs)
if (dupsIDs[x]==2) print x
}' infile |grep -f - infile
2016-09-27 GET /some/uri - reqId: 000-pat1-bgr, more text
2016-09-27 GET /some/uri - reqId: 0.215487, your favourite song
2016-09-27 reqCompleted: 0.215487, more characters
2016-09-27 reqCompleted: 000-pat1-bgr, more characters
Используя awk
, найденное решение:
awk 'BEGIN{FS=":|,";i=0;}
/reqCompleted/ || /reqId/{
arr[$i]=$2;
lines[$i]=$0;
i++;
}END{
for(key in arr){
if(arr[key] in arr){
}else{
print lines[key]
};
}
}' input.txt
Это дает ожидаемый вывод как:
2016-09-27 reqCompleted: 000-pat1-bgr, more characters
2016-09-27 GET /some/uri - reqId: 0.215487, your favourite song
2016-09-27 reqCompleted: 0.215487, more characters
2016-09-27 GET /some/uri - reqId: 000-pat1-bgr, more text