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.