Elimina tutte le righe che iniziano con un # da un file


182

Tutte le righe con commenti in un file iniziano con #. Come posso eliminare tutte le righe (e solo quelle righe) che iniziano con #? Altre righe contenenti #, ma non all'inizio della riga, devono essere ignorate.


1
Deve funzionare con la convenzione comune che #blah \<nl>blahconta come una singola "linea logica" perché la barra rovesciata sfugge alla nuova riga?
Sarnold,

@sarnold: a parte make, quali utility usano le "linee di giunzioni rovesciate prima di terminare un commento"? Le shell (bash e ksh testate) no. C e C ++ gestiscono lo splicing newline prima di altre elaborazioni delle direttive del preprocessore, ma sono direttive piuttosto che commenti.
Jonathan Leffler,

@Jonathan: Fantastico. Avevo supposto che la \<nl>fuga comune avrebbe funzionato anche sui commenti. Ma wow, ho sbagliato. Non sono ancora riuscito a trovare un altro esempio ... :) Grazie!
Sarnold,

Risposte:


302

Questo può essere fatto con un sed one-liner :

sed '/^#/d'

Questo dice "trova tutte le righe che iniziano con # ed eliminale, lasciando tutto il resto".


9
versione più breve:sed /^#/d
kev

80
Per i novizi di Linux come me:sed '/^#/ d' < inputFile.txt > outputFile.txt
Neil McGuigan,

50
La versione più breve: sed -i '/^#/d' filepath.
lesderid,

14
E sed -i '' '/^#/d' filepathsu Mac ( perché il suffisso -i è obbligatorio )
paulcm

1
@Viesturs Prova questo: awk '/^#/ && !first { first=1 ; next } { print $0}'
Raymond Hettinger il

56

Sono un po 'sorpreso che nessuno abbia suggerito la soluzione più ovvia:

grep -v '^#' filename

Questo risolve il problema come indicato.

Ma nota che una convenzione comune prevede che tutto, dalla #a alla fine di una riga, sia trattato come un commento:

sed 's/#.*$//' filename

sebbene questo consideri, ad esempio, un #carattere all'interno di una stringa letterale come l'inizio di un commento (che può o meno essere rilevante per il tuo caso) (e lascia righe vuote).

Una riga che inizia con uno spazio bianco arbitrario seguita da #potrebbe anche essere trattata come un commento:

grep -v '^ *#' filename

se lo spazio bianco è solo spazi, o

grep -v '^[  ]#' filename

dove i due spazi sono in realtà uno spazio seguito da un carattere di tabulazione letterale (digitare "control-v tab").

Per tutti questi comandi, omettere l' filenameargomento da leggere dall'input standard (ad esempio, come parte di una pipe).


Ho aggiunto una nuova risposta che si basa su questa risposta.
Acumenus

Ho avuto problemi con grep in questo modo su Windows. La soluzione è sostituire "con", ad esgrep -v "^#" filename
Serg

14

Il contrario della soluzione di Raymond:

sed -n '/^#/!p'

"non stampare nulla, tranne per le righe che NON iniziano con #"


9

puoi modificare direttamente il tuo file con

sed -i '/^#/ d'

Se si desidera eliminare anche le righe di commento che iniziano con alcuni spazi bianchi, utilizzare

sed -i '/^\s*#/ d'

Di solito, vuoi mantenere la prima riga dello script, se si tratta di uno sha-bang, quindi sednon dovresti eliminare le righe che iniziano con #!. inoltre dovrebbe eliminare le righe che contengono solo un hash ma nessun testo. metterli tutti insieme:

sed -i '/^\s*\(#[^!].*\|#$\)/d'

Per essere conforme a tutte le varianti sed è necessario aggiungere un'estensione di backup -iall'opzione:

sed -i.bak '/^\s*#/ d' $file
rm -Rf $file.bak

1
più 1 per quello che spazio
deepaksingh pawar

7

È possibile utilizzare quanto segue per una soluzione awk:

awk '/^#/ {sub(/#.*/,"");getline;}1' inputfile

5

Questa risposta si basa sulla risposta precedente di Keith .

egrep -v "^[[:blank:]]*#" dovrebbe filtrare le righe di commento.

egrep -v "^[[:blank:]]*(#|$)" dovrebbe filtrare sia i commenti che le righe vuote, come spesso è utile.

Per informazioni su [:blank:]e altre classi di caratteri, consultare https://en.wikipedia.org/wiki/Regular_expression#Character_classes .


Supponendo che la tua egrepsintassi supporti; le versioni precedenti potrebbero non esserlo.
Keith Thompson,

-3

Eccolo con un ciclo per tutti i file con qualche estensione:

ll -ltr *.filename_extension > list.lst

for i in $(cat list.lst | awk '{ print $8 }') # validate if it is the 8 column on ls 
do
    echo $i
    sed -i '/^#/d' $i
done
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.