bash:如何“动态”知道grep -A -B中的NUM选项?

时间:2010-04-16 00:35:50

标签: bash grep

我正在尝试从20个txt文件here的集合中分析我的代理结果。

如果您想知道背景信息,请参阅my page,我在这里做的只是一步。

基本上我只想从凌乱的上下文中获取我的代理的结果,所以我有一个单个文件的命令:

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 个答案:

答案 0 :(得分:3)

您可以使用sed来实现您的目标:

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

在此命令中,sed在找到与第一个模式匹配的行时开始打印行,并在找到与第二个模式匹配的行时停止,单独处理文件。

答案 1 :(得分:1)

使用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完成下一步操作。

只是来自home page的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