2013-09-22 17 views
7

Desidero estrarre le righe che non contengono # e eliminare ", ; nell'output.Awk: utilizzo della corrispondenza inversa su una stringa e sostituzione dei caratteri

mio file di input è simile al seguente:

# ;string"1" 
# string"2"; 
string"3"; 

Può usare grep e tr per ottenere l'output desiderato:

grep -v '#' FILE | tr -d ';"' 
string3 

Tuttavia voglio usare awk.

posso estrarre invertito partita awk '!/#/' FILE, ma come posso usare sub per eliminare ", ; nello stesso comando awk?

risposta

5

È possibile utilizzare gsub per la sostituzione globale:

awk '!/#/{gsub(/[";]/,"",$0);print}' 

La seguente trascrizione mostra in azione, offre la stesso risultato della pipeline grep/tr:

pax> echo '# ;string"1" 
# string"2"; 
string"3";' | awk '!/#/{gsub(/[";]/,"",$0);print}{}' 

string3 

Si noti che l'ultimo {} potrebbe non essere necessario in alcune implementazioni di awk ma è lì per interrompere l'output di righe non corrispondenti in tali implementazioni (di solito più vecchie) che lo fanno automaticamente per le linee che non corrispondono a nessuna delle regole.

+0

+1 per approccio corretto. Non è necessario l'argomento '$ 0' in' gsub() 'anche se questo è il default. –

3

Usa gsub invece che dovrebbe sostituire tutte le partite non solo:

awk '/#/{next}{gsub(/[";]/,"")}1' file 

uscita:

string3 
  • Saltare il terzo parametro per gsub rende elaborare $0 per impostazione predefinita.
  • /#/{next} rende saltare linee contenente #
  • 1 rende stampa $0
+0

Se il 'gsub' prima della prova per quello che la linea per la stampa, non è necessario il 'prossimo'. Vedi il mio post "Un'altra versione di awk". Perché hai il ',' all'interno di '[",;] '? Non era nella richiesta di sostituirlo, quindi può essere rimosso. – Jotne

+1

@Jotne La complessità sarebbe ancora la stessa e anche più complessa da quando sei tu d modificare il separatore globale in generale e anche usare 'OFS ='.Inoltre, prima di escludere una riga commentata avresti elaborato più volte l'utilizzo di gsub, in quanto ciò avrebbe dovuto elaborare la riga come non più necessaria. E questo è in realtà il motivo per cui non l'ho fatto. Grazie a proposito. Ho fatto l'aggiornamento. – konsolebox

+0

+1 per passare alla logica positiva ('salta le righe che contengono #' invece di 'selezionare le righe che NON contengono #') e quindi rendere il copione meno probabile che incorre in doppi negativi se potenziato in futuro. Probabilmente eccessivo per questo, ma il concetto generale di cercare di rendere le cose positive è generalmente buono. L'OP diceva 'linee CONTAINING #', tuttavia, non solo le righe che iniziano con '#', quindi è possibile rimuovere '^'. –

2

Un'altra awk versione

awk -F"[\";]" '{$1=$1} !/^#/' OFS= file 
string3 

awk '{gsub(/[";]/,x)} !/^#/' file 
string3 

Il x rappresenta nulla. Avrebbe potuto anche usato "", ma salva uno personaggi :)

2

Se si vuole dare una possibilità sed:

sed -n '/^[^#]/s/[";]//gp' file 
string3 
Problemi correlati