Получить последнее соответствующее строковое значение - PullRequest
0 голосов
/ 30 октября 2018

У меня есть файл, который содержит два значения для ключевого слова initial.... Я хочу получить самую последнюю дату для совпадения initial... строки. После получения даты мне также нужно отформатировать дату, заменив / на -

---other data
    INFO   | abc 1    | 2018/01/04 20:04:35 | initial...

    INFO   | abc 1    | 2018/02/05 17:01:42 | INFO | new| InitialLauncher | c.t.s.s.setup.launch | initial...

---other data

В приведенном выше примере мой вывод должен быть 2018-02-05. Здесь я выбираю строку, содержащую значение initial..., и получаю только строку с последним значением даты. Затем мне нужно удалить оставшуюся строку и извлечь только значение даты.

Я использую следующее grep, но оно еще не соответствует требованию.

grep -q -iF "initial..." /tmp/file.log

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

Grep только для (-o) нужной вам строки, сортируйте ее и обрезайте по первому слову:

grep -o '2[0-9]\{3\}/[0-9][0-9]/[0-9][0-9] [0-2][0-9]:[0-5][0-9]:[0-9][0-9] .* | initial' file.txt | sort | cut -d' ' -f1 | tai -1
0 голосов
/ 30 октября 2018

С учетом того, что более поздние даты появляются позже в файле, необходимо печатать только дату из последней строки, содержащей initial....

Первый шаг (сбросьте -q с grep - вы не хотите, чтобы он был тихим):

grep -iF 'initial...' /tmp/file.log |
tail -n 1 |
sed -e 's/^[^|]*|[^|]*| *\([^ ]*\) .*/\1/' -e 's%/%-%g'

(первая) команда s/// сопоставляет серию нетрубов, за которыми следует труба, еще одна серия нетрубов, за которыми следует труба, пробел, затем захватывает серию непробелов и, наконец, соответствует пустое и прочее; он заменяет все это только захваченной строкой, которая является полем даты после второго канала в строке ввода. (Вторая) команда s%%% заменяет косые черты на тире, используя %, чтобы избежать путаницы в том, что эквивалентный s/\//-/g может породить, тем самым переформатируя дату в формате ISO 8601.

Но мы можем потерять tail с:

grep -iF 'initial...' /tmp/file.log |
sed -n -e '$ { s/^[^|]*|[^|]*| *\([^ ]*\) .*/\1/; s%/%-%gp; }'

-n подавляет нормальный выход; $ соответствует только последней строке; p после второй операции s/// печатает результат.

Поиск по фиксированному шаблону без учета регистра удобнее записать в grep, чем в sed. Хотя это можно сделать с помощью одной команды sed, вам придется работать довольно усердно, сохраняя совпадающие строки в пространстве удержания, затем меняя местами удержание и пространство шаблона в конце, а также заменяя и печатая:

sed -n \
    -e '/[Ii][Nn][Ii][Tt][Ii][Aa][Ll]\.\.\./h' \
    -e '$ { x; s/^[^|]*|[^|]*| *\([^ ]*\) .*/\1/; s%/%-%gp; }' /tmp/file.log

Каждый из них создает вывод 2018-02-05 на данных выборки. Если вводить вход без initial..., они ничего не выводят.

0 голосов
/ 30 октября 2018

как то так ...

$ awk -F'|' '$NF~/initial\.\.\./ {if(max<$3) max=$3} 
             END  {gsub("/","-",max); 
                   split(max,dt," "); print dt[1]}' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...