2009-12-22 6 views

risposta

2

in Perl:

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

/B.*/ corrisponderà tutto ciò che contiene una B, che non inizia con una B. – rjh

+0

La domanda non ha indicato che la "B" dovrebbe essere all'inizio di una linea. –

+0

Scusa, hai ragione - dipende dalla nostra interpretazione. – rjh

5
sed '/^B/,$d' 

Leggi che nel modo seguente: Delete (d) tutte le linee che iniziano con la prima riga che inizia con una "B "(/^B/), su e fino all'ultima riga ($).

0

Se Perl è un possibilty, si potrebbe fare qualcosa di simile:

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

Sembra eccessivo leggere un intero file in memoria prima di fare qualsiasi cosa. – ephemient

7

se dall'inizio del file

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

se si desidera avviare da specifico numero di riga

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

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

Una spiegazione: lo switch -p aggiunge un anello intorno al codice, trasformandolo in questo:

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

L'ultima parola chiave esce dal ciclo che circonda immediatamente se la condizione è - in questo caso,/^ B /, che indica che la riga inizia con B.

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

Stampa dalla riga 1 alla/^ B/(inclusa). -n sopprime l'eco predefinito.


Aggiornamento: Opps ....non ha voluto "Bravo", così invece è necessaria l'azione inversa ;-)

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

/I3az/

+0

Sfortunatamente, questa stampa include la linea "Bravo", mentre la domanda vuole escludere la linea "Bravo". – ndim

+0

Arghh! ... non ha letto correttamente la domanda. Aggiornato con l'azione inversa "! P" (cioè stampa!) Per tutto ciò che non si trova tra/^ B/e alla fine del file. Mille grazie per aver individuato questo ndim. – draegtun

+0

Ah. '!' modifica un intervallo di indirizzi in modo che corrisponda solo al punto in cui non corrisponderebbe, e viceversa. Fa ancora parte dell'intervallo di indirizzi. Beh, '!' Era una novità per me ... grazie per avermi indicato. – ndim

1

Ecco un perl one-liner:

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

Proprio la condivisione di alcuni risposte che ho ricevuto:

dati di stampa a partire dalla prima linea, e continuare fino a trovare una corrispondenza per l'espressione regolare, poi si ferma:

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

dati di stampa a partire da prima linea, e continuare fino a trovare una corrispondenza per l'espressione regolare, ma senza mostrare la linea che corrisponde all'espressione regolare:

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

Farlo in sed:

<command> | sed -n '1,/<regex>/p' 
+0

L'operatore di flip flop è uno dei miei preferiti, e questa situazione è una delle poche volte che la uso. :) –

3

Alcuni dei sed comandi impartiti da altri continuerà a elaborare inutilmente l'ingresso dopo l'regex è trovato che potrebbe essere piuttosto lento per grandi ingresso. Questo si chiude quando viene trovata la regex:

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

Il tuo problema è una variante di una risposta in perlfaq6: How can I pull out lines between two patterns that are themselves on different lines?.


È possibile utilizzare .. operatore del Perl un po 'esotica (documentato in perlop):

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

Se si voleva linee di testo e non, si può usare

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

Ma se si vuoi occorrenze nidificate di START a END, ti imbatterai nel problema descritto nella domanda in questa sezione sulla corrispondenza del testo bilanciato.

Ecco un altro esempio di utilizzo ..:

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

uno di linea con i comandi di base: ha

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