Hallo,
guter Hinweis von hefee, das blinde paarweise Zusammenfügen reicht vermutlich nicht. Denn ich habe in meinem history.log auch Einträge dieser Art (also ohne die folgende "Commandline"):
Start-Date: 2015-01-22 18:11:10
End-Date: 2015-01-22 18:11:11
Start-Date: 2015-01-22 18:11:33
End-Date: 2015-01-22 18:11:33
Ich vermute, dass ich hier den Solver von Aptitude bei der Sicherheitsabfrage "Wollen Sie wirklich?" abgebrochen habe.
Dadurch kann also die paarweise Verkettung aus dem Takt kommen.
Mit perl könnte eine Lösung so aussehen ( Newline nur vor dem Wort Commandline durch Space ersetzen)
perl -0ne 's/\RCommandline/ Commandline/g; print;' /var/log/apt/history.log | grep Commandline
Nach einer kleinen Optimierung entfällt sowohl das Multiline-Reading (-0) als auch noch das anschliessende grep:
perl -ne 'chomp;print$l=(/^Com/)?"$l$_\n":"";$l="$_ "' /var/log/apt/history.log
Durch die Optionen -n wird dabei implizit folgendes ausgeführt:
#!/usr/bin/perl
# concatenate all lines beginning with "Commandline" with the previous line
use strict;
use warnings; # -w switch
{
while (<>) { # The -n switch reads filename arguments or STDIN
chomp; # remove trailing newline
if (/^Commandline/) { # actual record does begin with "Commandline"
print "$last$_\n" # append previous record with actual record
} else { # not yet found a Commandline!
print "" # so print nothing in this case (avoid grep)
}
$last = "$_ " # remember actual record until next loop
}
}
Okay, den else-Teil läßt man nun weg.
Schließlich kann man die -l Option verwenden, um chomp und print zu vereinfachen.
perl -wlne 'print "$last $_" if (/^Command/); $last=$_' /var/log/apt/history.log
oder
perl -wlne '/^Command/ && print "$last $_"; $last=$_' /var/log/apt/history.log
Die Syntax ist auf einmal wieder recht ähnlich zu awk:
awk '/^Command/ { print last " " $0;} { last=$0; }' /var/log/apt/history.log
oder sed:
sed '/^Com/!{h;d};/^Com/{x;G;s/\n/ /}' </var/log/apt/history.log
[edit: hier noch ein Oneliner in bash:]
while read line; do [[ $line =~ Commandline ]] && printf "%s %s\n" "$last" "$line"; last="$line"; done < /var/log/apt/history.log
perlish greetings
musca