使用grep和sed来过滤文本

时间:2014-03-17 18:48:43

标签: shell sed scripting grep

我有一个文本文件,其中包含一个由16位数字和一个名称组成的标题,以及一些被调用的函数:

  00000001000006c0 <_name>:
  ...
  100000730:    e8 8b ff ff ff          callq  1000006c0 <_func1>
  ...
  10000070c:    e8 7f 05 00 00          callq  100000c90 <_func2>
  ...
  0000000100000740 <_otherName>:
  ...
  100000730:    e8 8b ff ff ff          callq  1000006c0 <_func3>
  ...
  10000070c:    e8 7f 05 00 00          callq  100000c90 <_func4>
  ...

我需要从标题中获取名称并将其功能附加到它们。有点像:

 name -- func1
 name -- func2
 otherName -- func3
 otherName -- func4

我设法通过此命令获取标题名称:

 grep -o '\w*>:$' | sed 's/_//' | sed 's/>://' | cat > headingNames.tmp

但我最终得到了标题名称。你能帮我一点吗?

4 个答案:

答案 0 :(得分:3)

我会用awk + ​​tr

来做
<INPUT_FILE awk 'NF==2 {header=$2} NF>2 {print header, "--", $NF}' | tr -d '<_>:'

您提供的示例文件的输出:

name -- func1
name -- func2
otherName -- func3
otherName -- func4

你需要保持跨行的状态,所以只使用sed和grep会很棘手。另一方面,Awk非常适合这种情况。

答案 1 :(得分:2)

使用awk:

awk '{p=$0;gsub(/[<>:]/, "")} p ~ /:$/ && NF==2{name=$2;next} NF>2{print name, "--", $NF} ' file
_name -- _func1
_name -- _func2
_otherName -- _func3
_otherName -- _func4

答案 2 :(得分:2)

我使用Perl,但我肯定你可以使用sed,你确实可以:

/^[0-9a-fA-F][0-9a-fA-F]* </{s/.*<_*\(.*\)>.*/\1/;h;d;}
/<.*>/{G;s/.*<_*\(.*\)>\n\(.*\)/\2 -- \1/p;}
d

请不要; - )

除了callq之外,抑制输出仍然是读者的练习。 (提示:第2行。)

更新:perl版本,因为Tom Fenech希望看到它。完全没有修饰,因为做一个sed版本更有趣:

#!/usr/bin/perl -w
use strict;
use warnings;


my $current = "";

while (<>)
{
  if (/^[0-9a-f]{16} <_?(.*)>:/)
  {
    $current = $1;
    next;
  }

  print "$current -- $1\n" if /.* <(.*)>/;
}

答案 3 :(得分:1)

这可能适合你(GNU sed):

sed -nr '/^\s*\S{16}/{h;d};G;s/.*<_(.*)>.*<_(.*)>.*/\2 -- \1/p' file

复制标题,将其附加到非标题行,然后在适用时提取它和函数名称。