Извлечь только числа из строки текстового файла

Вывод определенной команды содержит

 >> ..................546 Jobs Retrieved 
    List of jobs Retrieved: 1-4,6-12,14,2017-2018 ............
 >>> 30 Jobs Done
    Jobs terminated: retrieve them with: crab -getoutput <List of jobs>
    List of jobs: 203,376,578,765,803,809,811
.....................

И я хочу извлечь только 203 376 578 765 803 809 811, которые появляются после строки 30 Jobs Done. И после этого мне нужно поместить это число в виде строки в определенную переменную, чтобы использовать это в какой-то команде. Как мне это сделать.

Я попробовал это следующим образом:

  1. Я помещаю вывод в файл status.log
  2. $ sed -e '1,/Выполнено/d' status.log | grep "Список вакансий:" то я получил только строку Список вакансий: 578 765 811 836 1068 1096 1128 но мне не нужна фраза "Список вакансий"

Помогите мне, пожалуйста.

Заранее большое спасибо.


person ramkrishna    schedule 25.03.2014    source источник
comment
Блок, который вы показываете, повторяется в вашем файле или только один раз? Список заданий всегда идет ровно через 2 строки после выполненных заданий?   -  person Mark Setchell    schedule 25.03.2014
comment
Список заданий появляется несколько раз, но «Выполненные задания» появляются только один раз в выходных данных, и да, «Список заданий» всегда появляется ровно через 2 строки после «Выполненных заданий».   -  person ramkrishna    schedule 25.03.2014


Ответы (3)


Вы можете использовать это:

awk '/30 Jobs Done/ {f=1;next} f && /List of jobs:/ {print $4;exit}' file
203,376,578,765,803,809,811

Когда он находит 30 Jobs Done, он устанавливает флаг f в значение true.
Если затем он находит List of jobs: и флаг f равен true, выведите поле 4

person Jotne    schedule 25.03.2014
comment
30 Jobs Done вероятно плохой шаблон \d+ Jobs Done было бы намного лучше. Кроме того, было бы неплохо объяснить, как работает скрипт. - person Aaron Digulla; 25.03.2014
comment
@AaronDigulla Я не уверен, OP специально запрашивает данные после 30 Jobs Done PS \d+ не работает в моем awk, поэтому тогда будет [0-9]+ Jobs Done - person Jotne; 25.03.2014
comment
@Jotne Спасибо. Еще одна вещь: теперь я хотел бы поместить вывод этой команды в переменную, поэтому я использую jobs=$(awk '/Jobs Done/ {f=1;next} f && /List of jobs:/ {print $4;exit } 'status.log) Но выдает ошибку как недопустимое имя переменной. - person ramkrishna; 25.03.2014
comment
У меня работает нормально: var=$(awk '/30 Jobs Done/ {f=1;next} f && /List of jobs:/ {print $4;exit}' file) echo $var 203,376,578,765,803,809,811 - person Jotne; 25.03.2014
comment
Я не знаю почему, но это не работает для меня. Есть ли другая альтернатива? - person ramkrishna; 25.03.2014
comment
Получил ошибку. Я использую оболочку tcsh, поэтому это происходит. теперь я использую set var=awk '/Jobs Done/ {f=1;next} f && /List of jobs:/ {print $4;exit}' status.log Но я не получаю правильный результат echo $var Список заданий: 203 376 578 765 803 809 811 - person ramkrishna; 25.03.2014
comment
Понятно: set var='awk '/Задания выполнены/ {f=1;следующий} f && /Список заданий:/ {print $4;exit}' status.log' - person ramkrishna; 25.03.2014
comment
Не пишите сценарии оболочки в [t]csh. Гугл сш почему бы и нет. - person Ed Morton; 25.03.2014

С помощью простых инструментов:

egrep '^\s+List of jobs: [0-9,]+$' status.log | cut -d: -f2

Шаблон для egrep соответствует всей строке, а cut возвращает все после :.

Это означает, что вы получите ведущее место в результате. Если это проблема:

egrep '^\s+List of jobs: [0-9,]+$' status.log | cut -d: -f2 | cut -c2-
person Aaron Digulla    schedule 25.03.2014

Вы можете сделать это:

grep -A2 "Jobs Done" yourfile | awk '/List of jobs:/{print $4}'

Возьмите две строки после «Выполненные задания» (-A2), а затем найдите «Список заданий» с помощью awk и напечатайте 4-е поле.

person Mark Setchell    schedule 25.03.2014
comment
+1 за простоту. Я не знаю, почему люди не одобряют использование труб. Не эта ли особенность сделала его таким популярным! - person jaypal singh; 25.03.2014