Header / Kommentarblöcke abrufen

1181
AnC

Ich habe eine Reihe von Protokolldateien, die folgendermaßen aussehen:

/* header arbitrary number of lines */ blah blah blah blah 

Wie kann ich mit einfachen Bash-Befehlen (vorzugsweise sed, nicht awk) nur die Kopfzeilen abrufen (idealerweise einschließlich der Kommentarmarken)?

Ich habe RTFM und habe googeln versucht, auch ein paar Hinweise gefunden, aber nicht genug, um mich anzufangen .

Vielen Dank!

1
Ein weiterer verwandter Link: http://www.cyberciti.biz/faq/sed-howto-remove-lines-paragraphs/ Das tut das Gegenteil von dem, was ich brauche. AnC vor 15 Jahren 0

4 Antworten auf die Frage

2
nik

Wenn Sie die folgenden Dinge bestätigen, funktioniert das Skript in dieser Antwort für Sie.

  1. Dateien beginnen mit den /*Zeichen " "
    • Es kann einen mehrzeiligen C-Syntex-Kommentarblock geben, der nicht verschachtelt ist
    • Der Kommentarblock endet ohne zusätzliche C-Anweisungen in derselben Zeile
sed -n '/ ^ \ / \ * /, / \ * \ // p' file.c # - - - - -  

Dadurch werden alle Zeilen vom Anfang der Datei bis zum Ende des Kommentarblocks abgeglichen.
Die zweite Zeile (mit einem " #" am Anfang) markiert das gesuchte Match.
Das " -n" am Anfang und das " p" am Ende geben an, nur den passenden Teil zu drucken.

@AnC, ich denke, es gibt auch ein Problem in meiner Lösung. Es hört nicht auf wie der Befehl von Richard nach dem ersten Match! Sie erhalten also alle Kommentare, die in neuen Zeilen beginnen (Anforderung 1 ist nicht auf den Beginn der Datei beschränkt) in einer Datei. nik vor 15 Jahren 0
Ich habe gerade realisiert, dass ich jetzt beide Lösungen kombiniere: cat $ LOGFILE | sed -e '/ \ * \ // q' | sed -n '/ ^ \ / \ * /, / \ * \ // p' Leider kann ich Ihnen nicht beide gutschreiben. AnC vor 15 Jahren 0
@AnC, Sie könnten Folgendes tun: `sed -n '/ ^ \ / * /, / * \ // p' $ LOGFILE | sed -e "/ * \ // q" und überspringt die "Katze". Aber ich bin noch nicht glücklich darüber. nik vor 15 Jahren 0
1
Richard Hoskins

Schauen Sie sich jede Datei mit der Erweiterung .log an. Wenn die erste Zeile nur "/ *" ist, drucken Sie alles bis zu einer Zeile mit "* /".

for file in *.log; do head -n1 $file | grep -q '^/*' && sed '/^\*\/$/q' $file;  done 
Das macht den Job - danke! Ein Nachteil: Es funktioniert nicht, wenn sich etwas über der Kopfzeile befindet oder wenn mehrere Kommentarblöcke vorhanden sind. Ich sollte mich jedoch nicht darum kümmern, bis ich es wirklich brauche. AnC vor 15 Jahren 1
Und wenn es keine Kopfzeile gibt, wird die gesamte Datei gedruckt! Es gibt viele Fehlermodi. Vielleicht können Sie die Frage stellen "Wie kann ich Kommentare in einer Datei drucken?" (Und bitte lassen Sie uns awk verwenden.) Richard Hoskins vor 15 Jahren 0
Du hast recht - die Lösung von Nik scheint in dieser Hinsicht etwas sicherer zu sein. Danke noch einmal! AnC vor 15 Jahren 0
Ich habe meine Antwort aktualisiert, um die meisten der schlimmsten Probleme zu beseitigen. Richard Hoskins vor 15 Jahren 0
Interessanter Ansatz. Jetzt bin ich hin und her gerissen zwischen der Kombination beider Lösungen (siehe Kommentar oben) ... AnC vor 15 Jahren 0
Beide Lösungen haben Probleme. Wenn einer von ihnen für * Ihre spezifischen Umstände * arbeitet, hatten wir Glück. Wenn Sie eine allgemeinere Lösung wünschen, (Husten) Perl (Husten). http://search.cpan.org/~mschilli/File-Comments-0.07/lib/File/Comments.pm Richard Hoskins vor 15 Jahren 0
Sie haben recht, für komplexere Aufgaben sollte eine "richtige" Skriptsprache verwendet werden. Danke für diesen Link! AnC vor 15 Jahren 0
0
Defiant91
cat *.log | sed -e 's/*\/\*//g' -e 's/\*\///g' >> smt.log 

Das könnte es sein

Ich befürchte, dass nur die "* /" - Zeile entfernt wird. Ich habe mit ähnlichen Ausdrücken experimentiert, bin aber nirgendwohin gekommen - ich denke, das liegt daran, dass sed zeilenweise funktioniert. AnC vor 15 Jahren 0
0
Greg K

Falls Sie wie ich auf diese Frage gestoßen sind, als Sie versuchten, Kommentare im Doxygen-Stil abzurufen, lautet der sed-Befehl:

sed -n '/^\/\*/p; /^ \*/p' < file 

Für eine detailliertere Erklärung habe ich darüber gebloggt .