Você pode fazer isso com o awk, mantendo matrizes para o título e ano do livro, assim como para os trabalhos. No seu exemplo, não há anos para os artigos, então eles são simplesmente listados na segunda coluna como título.
Aqui está um exemplo:
#!/usr/bin/awk -f
function finish() {
rows = book;
if (rows < paper) rows = paper;
for (n = 0; n <= rows; ++n) {
printf "%-15s %-25s %-8s %s\n",
author,
n <= book ? books[n] : "-",
n <= book ? years[n] : "-",
n <= paper ? papers[n] : "-";
}
book = -1;
paper = -1;
}
BEGIN {
author = "?";
book = -1;
paper = -1;
printf "Author Books year Papers\n";
}
/^[[:space:]]*Author[[:space:]]/ {
finish();
author = $0;
sub("^[^[:space:]]+[[:space:]]+", "", author);
sub("[[:space:]]+$", "", author);
next;
}
/^[[:space:]]*(e)?paper[[:space:]]/ {
++paper;
item = $0;
sub("^[^[:space:]]+[[:space:]]+", "", item);
sub("[[:space:]]+$", "", item);
papers[paper] = item;
next;
}
/^[[:space:]]*([eE])?[bB]ook[[:space:]].*year[[:space:]]+[[:digit:]]+[[:space:]]*$/ {
++book;
item = $0;
sub("^[^[:space:]]*[[:space:]]*", "", item);
sub("[[:space:]]+$", "", item);
title = item;
sub("[[:space:]]*year[[:space:]]+[[:digit:]]+$", "", title);
year = item;
sub("^.*year[[:space:]]+", "", year);
books[book] = title;
years[book] = year;
next;
}
END {
finish();
}
com saída:
$ ./foo <foo.in
Author Books year Papers
E. Narayanan Astrophysics 2001 Intelligent Transportation
E. Narayanan General Mechanics 2010 Nanotechnology Magazine
E. Narayanan Nuclear physics 2011 -
R Ramesh Organic Chemistry 2007 Ionic Batteries
R Ramesh Physical chemistry 2008 solar photocatalytic oxidation processes
R Ramesh - - Biological oxidation