Quindi apri un file con cat
e poi usando grep
ottenere righe corrispondenti mi porta così lontano solo quando lavoro con il particolare set di registri con cui ho a che fare. Ha bisogno di un modo per abbinare le linee a un modello, ma solo per restituire la parte della linea dopo la corrispondenza. La porzione prima e dopo la partita varierà costantemente. Ho giocato con sed
o awk
, ma non sono stato in grado di capire come filtrare la riga per eliminare la parte prima della corrispondenza o semplicemente restituire la parte dopo la corrispondenza, entrambi funzioneranno.
Questo è un esempio di una riga di cui ho bisogno per filtrare:
2011-11-07T05:37:43-08:00 <0.4> isi-udb5-ash4-1(id1) /boot/kernel.amd64/kernel: [gmp_info.c:1758](pid 40370="kt: gmp-drive-updat")(tid=100872) new group: <15,1773>: { 1:0-25,27-34,37-38, 2:0-33,35-36, 3:0-35, 4:0-9,11-14,16-32,34-38, 5:0-35, 6:0-15,17-36, 7:0-16,18-36, 8:0-14,16-32,34-36, 9:0-10,12-36, 10-11:0-35, 12:0-5,7-30,32-35, 13-19:0-35, 20:0,2-35, down: 8:15, soft_failed: 1:27, 8:15, stalled: 12:6,31, 20:1 }
La porzione di cui ho bisogno è tutto ciò che è stato “bloccato”.
Lo sfondo dietro questo è che posso scoprire quanto spesso qualcosa si blocca:
cat messages | grep stalled | wc -l
Quello che devo fare è scoprire quante volte un certo nodo si è bloccato (indicato dalla porzione prima di ogni due punti dopo "stallo". Se eseguo solo grep per quello (cioè 20:) potrebbe restituire righe che hanno errori soft, ma no stall, il che non mi aiuta. Ho bisogno di filtrare solo la parte in stallo in modo da poter quindi cercare un nodo specifico tra quelli che si sono bloccati.
A tutti gli effetti, questo è un sistema freebsd con utilità di base GNU standard, ma non posso installare nulla in più per aiutare.
Risposta accettata:
Lo strumento canonico per questo sarebbe sed
.
sed -n -e 's/^.*stalled: //p'
Spiegazione dettagliata:
-n
significa non stampare nulla per impostazione predefinita.-e
è seguito da un comando sed.s
è il comando di sostituzione del modello.- L'espressione regolare
^.*stalled:
corrisponde al modello che stai cercando, più qualsiasi testo precedente (.*
intendendo qualsiasi testo, con un^
iniziale per dire che la partita inizia all'inizio della riga). Nota che sestalled:
compare più volte sulla riga, corrisponderà all'ultima occorrenza. - La partita, ovvero tutto ciò che è in coda fino a
stalled:
, viene sostituito dalla stringa vuota (cioè eliminata). - Il
p
finale significa stampare la riga trasformata.
Se vuoi conservare la parte corrispondente, usa un backreference:1
nella parte di ricambio indica cosa c'è all'interno di un gruppo (…)
nel modello. Qui puoi scrivere stalled:
sempre nella parte di ricambio; questa funzione è utile quando il pattern che stai cercando è più generale di una semplice stringa.
sed -n -e 's/^.*(stalled: )/1/p'
A volte vorrai rimuovere la parte della linea dopo la partita. Puoi includerlo nella corrispondenza includendo .*$
alla fine del pattern (qualsiasi testo .*
seguito dalla fine della riga $
). A meno che tu non inserisca quella parte in un gruppo a cui fai riferimento nel testo sostitutivo, la fine della riga non sarà nell'output.
Come ulteriore illustrazione di gruppi e backreference, questo comando scambia la parte prima della partita e la parte dopo la partita.
sed -n -e 's/^(.*)(stalled: )(.*)$/321/p'