Come trovare le righe che iniziano con **


8

Devo scoprire se iniziano le righe di un file **.

Non riesco a capire come farlo perché *viene interpretato come un jolly dalla shell.

grep -i "^2" test.out

funziona se la linea inizia con un 2 ma

grep -i "^**" test.out 

ovviamente non funziona.

(Devo anche sapere se questa riga termina con un )ma non ci ho ancora provato).

Risposte:


18

Usa il \personaggio per sfuggire al * per renderlo un personaggio normale.

grep '^\*\*' test.out

Nota anche la virgoletta singola 'e non quella doppia "per evitare che la shell espanda le cose


3
Il primo *non ha bisogno di scappare in questo caso particolare, prima guerra mondiale.
don_crissti,

5
Anche se non deve essere evitato, non fuggire dal primo asterisco sarà più confuso da un osservatore casuale, come se abbinassi "qualsiasi numero di inizi di linee seguiti da un asterisco". Tutto ciò che rende una regexp più intuitiva per un manutentore è una buona idea. =)
Conspicuous Compiler

1
L'uso delle virgolette doppie impedirebbe anche l'espansione, non solo le virgolette singole. Consiglio sbagliato qui.
rems4e,

@ rems4e l'uso di virgolette doppie impedirebbe alla shell di espandere gli asterischi, ma non di interpretare le barre rovesciate. Con le virgolette, dovresti usare in grep "^\\*\\*"modo che grep riceva la ^\*\*stringa di cui ha bisogno per evitare di interpretare gli asterischi come quantificatori regex.
Aaron,

7

Se desideri controllare la linea che inizia con **e termina con ), puoi combinare due grepoperazioni in questo modo,

grep '^*\*' test.out | grep ')$'

O con un singolo grepcomando come questo,

grep -E '^\*\*.*\)$' test.out

Spiegazione

  • ^\*\* : linea di corrispondenza che inizia con **
  • .* : abbina tutto dopo **
  • \)$: linea di corrispondenza che ha anche )alla fine della linea.

3

Non è il guscio

Nessuna delle risposte finora ha toccato il vero problema. Sarebbe utile spiegare perché non funziona come previsto.

grep -i "^**" test.out

Poiché hai citato il modello in grep , non* viene espanso dalla shell. Viene passato a grep così com'è. Questo è spiegato nella pagina di manuale [1] per bash [2] :

Racchiudere i caratteri tra virgolette doppie conserva il valore letterale di tutti i caratteri tra virgolette, ad eccezione di $, `, \ e, quando l'espansione della cronologia è abilitata,!.

Sono espressioni regolari ordinarie regolari

Un'espressione regolare è un modello che descrive un insieme di stringhe.

*è uno dei modelli chiave nelle espressioni regolari. Per impostazione predefinita, grep lo interpreta come segue:

* The preceding item will be matched zero or more times.

Ciò significa che il tuo modello così com'è, ^**non ha molto senso. Forse cerca di far coincidere l'inizio della riga zero o più volte , due volte. Qualsiasi cosa significhi.

La soluzione è citarla :

Qualsiasi meta-personaggio con significato speciale può essere citato precedendolo con una barra rovesciata.

grep -i "^\*\*" test.out


[1] Non consiglio di leggerlo. Si prega di utilizzare man dasho simili invece.

[2] Nessuna shell è stata data, quindi presumo bash .


2

Altre opzioni.

Puoi usare sedo awkanche

$ sed -n '/^*\*/p' test.out
$ awk '/^*\*/' test.out

Per conoscere le righe che terminano con l' )uso anche grepo sedoawk

$ grep ')$' test.out
$ sed -n '/)$/p' test.out
$ awk '/)$/' test.out

Grazie a tutti ! Apprezzo molto l'aiuto su questo!
Shar Hunter,

1
E la linea awk combinata: '/^*\*/&&/)$/'...
jasonwryan il

0

Questa è la versione completamente non quotate: grep ^\\*\\* test.out. Per passare una backslash letterale dalla shell a grep, deve essere evitato.

Funziona finché non ci sono file nella directory che iniziano ^\e contengono un'altra barra rovesciata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.