bash: как узнать NUM-опцию в grep -A -B "на лету"? - PullRequest
3 голосов
/ 16 апреля 2010

Я пытаюсь проанализировать результаты моего агента из коллекции из 20 текстовых файлов здесь .

Если вам интересна справочная информация, перейдите по ссылке моя страница , то, что я здесь делаю, это только один шаг.

По сути, я хотел бы вывести только результат моего агента из грязного контекста, поэтому у меня есть эта команда для одного файла:

cat run15.txt | grep -A 50 -E '^Agent Name: agent10479475' | grep -B 50 '^=='

Это означает: после совпадения с регулярным выражением продолжайте движение вперед на 50 строк, останавливайтесь, затем сопоставляйте разделитель строк, начинающийся с "==", по возможности возвращайтесь на 50 строк назад (это, безусловно, приведет к конфликту самой первой строки).

Этот подход зависит от того факта, что жестко запрограммированный счетчик номеров строк 50, было бы просто прекрасно получить ровно один разделитель строк.

И это не будет работать, если я сделаю следующий код:

cat run*.txt | grep -A 50 -E '^Agent Name: agent10479475' | grep -B 50 '^=='

На выходе будет беспорядок ...

Мой вопрос: как убедиться, что grep точно знает, когда прекратить движение вперед, а когда перестать двигаться назад?

Любое предложение или подсказка очень ценится.

Отредактировано: я снова делал что-то нелегкое, опять-таки ... Гуру Bash предлагают несколько более мощных инструментов. Я, конечно, с этого момента переключусь на sed или awk. Это мой подход в конце, после проб и ошибок:

NUM=10479475 
for i in {1..20}; do cat "run$i.txt" | grep -A 50 -E "^Agent Name: agent_*$NUM"
| grep -B 50 '^==';done > myresults.txt

Ответы [ 2 ]

3 голосов
/ 16 апреля 2010

Вы можете использовать sed для достижения того, что вы хотите:

sed -s -n -e '/^Agent Name: agent10479475/,/^==/ p' run*.txt

В этой команде sed начинает печать строк, когда находит строку, соответствующую первому шаблону, и останавливается, когда находит строку, соответствующую второму шаблону, обрабатывая файлы отдельно.

1 голос
/ 16 апреля 2010

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

awk 'BEGIN{RS="==*"}
/Agent Name: agent10479475/{
  print "-->"$0
}' file

выход

$ ./shell.sh
-->
Agent Name: agent10479475
Bank Balance: $4356
Buy bids placed: 87
Desired assets --
  ticket_10960: Quantity(0),  Desired Quantity(1)
  ticket_11162: Quantity(0),  Desired Quantity(2)
  ticket_11213: Quantity(0),  Desired Quantity(1)
  ticket_11334: Quantity(0),  Desired Quantity(1)
  ticket_11425: Quantity(0),  Desired Quantity(3)
  ticket_11510: Quantity(0),  Desired Quantity(1)
  ticket_11732: Quantity(0),  Desired Quantity(2)
  ticket_11843: Quantity(1),  Desired Quantity(1)
  ticket_11904: Quantity(0),  Desired Quantity(1)
  ticket_12035: Quantity(0),  Desired Quantity(3)
  ticket_12120: Quantity(0),  Desired Quantity(1)
  ticket_12332: Quantity(0),  Desired Quantity(2)
  ticket_12433: Quantity(0),  Desired Quantity(1)
  ticket_12564: Quantity(1),  Desired Quantity(1)
  ticket_12645: Quantity(0),  Desired Quantity(3)
  flight to melbourne: Quantity(8),  Desired Quantity(8)
  room: Quantity(32),  Desired Quantity(24)
Negative quantity assets --
  ticket_7401: Quantity(-14)
  ticket_22013: Quantity(-15)
  ticket_28401: Quantity(-14)
Remaining assets --
  ticket_6463: Quantity(1)
  ticket_9861: Quantity(1)
  ticket_13441: Quantity(1)
  ticket_20813: Quantity(1)
  ticket_26853: Quantity(1)

Команда awk сообщает, что установите разделитель записей (RS) в строки "====", поэтому каждая запись теперь содержит Agent: до следующей записи Agent:. Вы можете делать все, что захотите, используя $0.

Просто примечание от вашей домашней страницы скрипт Perl, у вас есть эта строка

$line = s/^\s+[0-9]+//;

при переборе файла bids.txt. Вы уверены, что хотите этого? Это говорит, чтобы удалить начальные пробелы и цифры. Если это так, у вас не будет номера, чтобы добавить уже. Все ваши cat + grep + cut и функция усреднения скрипта Perl также могут быть объединены с помощью awk

awk 'BEGIN{
  printf "Enter agent num: "
  getline num <"-"
  regex="Agent Name: agent"num
  RS="==*"
  FS="\n"
}
$0 ~ regex{
  for(i=1;i<=NF;i++){
    if($i~/Buy bids placed:/){
       m=split($i, bids,": ")
       print bids[2]
       avgbids[num]++
       total+=bids[2]
    }
  }
}
END{
  for(i in avgbids) print i, total/avgbids[i]
}' run*txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...