2009-12-22 5 views

Antwort

2

in Perl:

perl -nle '/B.*/ && last; print; ' source.txt 
+0

/B.*/ wird alles, die ein B entspricht, nicht mit einem B beginnen – rjh

+0

Die Frage besagt nicht, dass das "B" am Anfang einer Linie stehen sollte. –

+0

Entschuldigung, du hast recht - es liegt an unserer Interpretation dort. – rjh

5
sed '/^B/,$d' 

lesen, dass Sie wie folgt vor: Löschen (d) alle Zeilen mit der ersten Zeile beginnen, die mit einem „B beginnt "(/^B/), hoch und bis zur letzten Zeile ($).

0

Wenn Perl eine Möglichkeit ist, könnten Sie so etwas tun:

% perl -0ne 'if (/B.*/) { print $`; last }' INPUT_FILE 
+0

Es scheint exzessiv zu sein, eine ganze Datei in den Speicher einzulesen, bevor Sie etwas tun. – ephemient

7

Wenn es von Anfang der Datei

awk '/^B/{exit}1' file 

, wenn Sie von bestimmten Zeilennummer starten wollen

awk '/^B/{exit}NR>=10' file # start from line 10 
11

perl -pe 'last if /^B/' source.txt

Eine Erklärung: Die -p Schalter eine Schleife um den Code hinzufügt, ist es in diese Wende:

 
while (<>) { 
    last if /^B.*/; # The bit we provide 
    print; 
} 

Das letzte Schlüsselwort sofort die umgebende Schleife beendet, wenn die Bedingung erfüllt ist - in diesem Fall/^ B /, was bedeutet, dass die Zeile mit einem B beginnt.

6
sed -n '1,/^B/p' 

Drucken von Zeile 1 bis/^ B/(inklusive). -n unterdrückt das Standardecho.


Aktualisierung: Opps ....wollte nicht "Bravo", so stattdessen die umgekehrte Wirkung benötigt ;-)

sed -n '/^B/,$!p' 

/I3az/

+0

Leider druckt dies auch die "Bravo" Zeile, während die Frage die "Bravo" Zeile ausschließen möchte. – ndim

+0

Arghh! ... hat die Frage nicht richtig gelesen. Aktualisiert mit umgekehrter Aktion "! P" (dh. Print!) Für alles nicht zwischen/^ B/und Dateiende. Vielen Dank, dass Sie diesen ndim entdeckt haben. – draegtun

+0

Ah. '!' ändert einen Adressbereich so, dass er nur dort übereinstimmt, wo er nicht übereinstimmt und umgekehrt. Es ist immer noch Teil des Adressbereichs. Nun, '!' War neu für mich ... danke, dass du mich darauf hingewiesen hast. – ndim

1

Hier ist ein Perl-Einzeiler:

perl -pe 'last if /B/' file 
2

Nur einige teilen ich habe Antworten erhalten:

Druckdaten in der ersten Zeile beginnen, und weiter, bis wir eine Übereinstimmung mit dem regulären Ausdruck finden, dann stoppen:

<command> | perl -n -e 'print "$_" if 1 ... /<regex>/;' 

Druckdaten in der ersten Zeile beginnen, und weiter, bis wir eine Übereinstimmung mit dem regulären Ausdruck finden, aber die Zeile nicht angezeigt werden, die den regulären Ausdruck:

<command> | perl -pe '/<regex>/ && exit;' 

es in sed tun:

+0

Der Flipflop-Operator ist einer meiner Favoriten, und diese Situation ist einer der wenigen Male, die ich es benutze. :) –

3

Einige der sed Befehle, die von anderen gegeben werden, werden die Eingabe unnötigerweise weiter verarbeiten, nachdem die Regex gefunden wurde, was für große Eingaben ziemlich langsam sein könnte. Dies wird beendet, wenn der Regex gefunden wird:

sed -n '/^Bravo/q;p' 
2

Ihr Problem ist eine Variation auf einer Antwort in perlfaq6: How can I pull out lines between two patterns that are themselves on different lines?.


können Sie Perl verwenden etwas exotischen .. Operator (in perlop dokumentiert):

perl -ne 'print if /START/ .. /END/' file1 file2 ... 

Wenn Sie Text und nicht die Linien wollten, würden Sie

perl -0777 -ne 'print "$1\n" while /START(.*?)END/gs' file1 file2 ... 

verwenden, aber wenn Sie Wenn Sie geschachtelte Vorkommen von START bis END möchten, stoßen Sie auf das Problem, das in der Frage in diesem Abschnitt zum Abgleich von Text beschrieben wird.

Hier ist ein weiteres Beispiel für die Verwendung ..:

while (<>) { 
    $in_header = 1 .. /^$/; 
    $in_body = /^$/ .. eof; 
# now choose between them 
} continue { 
    $. = 0 if eof; # fix $. 
} 
0

Einzeiler mit grundlegenden Shell-Kommandos:

head -`grep -n B file|head -1|cut -f1 -d":"` file 
Verwandte Themen