imre
imre

Reputation: 489

Using grep and sed to filter through text

I have a text file containing a heading which consists of 16 digits and a name, and a couple of called functions:

  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>
  ...

I need to get the names from the headings and append their functions to them. Something along the lines of:

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

I managed to get the heading names out through this command:

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

But I just end up with heading names. Can you please give me a little push?

Upvotes: 1

Views: 82

Answers (4)

potong
potong

Reputation: 58578

This might work for you (GNU sed):

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

Copy the heading, append it to non-heading lines and then extract it and the function names when applicable.

Upvotes: 1

user3392484
user3392484

Reputation: 1919

I'd use Perl, but I was sure that you could use sed, and you indeed can:

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

please don't though ;-)

Suppressing output except for callq is left as an exercise for the reader. (Hint: line 2.)

Update: perl version because Tom Fenech wanted to see it. Entirely unpolished, because doing a sed version was more entertaining:

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


my $current = "";

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

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

Upvotes: 2

anubhava
anubhava

Reputation: 786349

Using 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

Upvotes: 2

toth
toth

Reputation: 2552

I would do it with awk+tr

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

Output for your provided sample file:

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

You need to keep state across lines, so it's going to be tricky using only sed and grep. Awk on the other hand, is perfect for this.

Upvotes: 3

Related Questions