Eliminar todas las líneas que comienzan con un # de un archivo

182

Todas las líneas con comentarios en un archivo comienzan con #. ¿Cómo puedo eliminar todas las líneas (y solo aquellas) que comienzan con #? Se #deben ignorar otras líneas que contengan , pero no al principio de la línea.

Pueblo
fuente
1
¿Tiene que funcionar con la convención común que #blah \<nl>blahcuenta como una sola "línea lógica" porque la barra diagonal inversa escapa a la nueva línea?
sarnold
@sarnold: aparte de make, ¿qué utilidades usan las 'líneas de empalme de barra diagonal inversa antes de finalizar un comentario'? Los shells (bash y ksh probados) no. C y C ++ manejan el empalme de nueva línea antes de otro procesamiento de directivas de preprocesador, pero son directivas en lugar de comentarios.
Jonathan Leffler el
@ Jonathan: Impresionante. Asumí que el \<nl>escape común también funcionaría en los comentarios. Pero wow, estaba equivocado. Todavía no he podido encontrar otro ejemplo ... :) ¡Gracias!
sarnold

Respuestas:

302

Esto se puede hacer con un sed one-liner :

sed '/^#/d'

Esto dice, "encuentre todas las líneas que comienzan con # y elimínelas, dejando todo lo demás".

Raymond Hettinger
fuente
9
versión más corta:sed /^#/d
kev
80
Para novatos de Linux como yo:sed '/^#/ d' < inputFile.txt > outputFile.txt
Neil McGuigan
50
Versión más corta: sed -i '/^#/d' filepath.
lesderid
14
Y sed -i '' '/^#/d' filepathen Mac ( porque el sufijo -i es obligatorio )
paulcm
1
@Viesturs Pruebe esto: awk '/^#/ && !first { first=1 ; next } { print $0}'
Raymond Hettinger
56

Estoy un poco sorprendido de que nadie haya sugerido la solución más obvia:

grep -v '^#' filename

Esto resuelve el problema como se indicó.

Pero tenga en cuenta que una convención común es que todo, desde #el final de una línea, se trate como un comentario:

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

aunque eso trata, por ejemplo, un #carácter dentro de un literal de cadena como el comienzo de un comentario (que puede o no ser relevante para su caso) (y deja líneas vacías).

Una línea que comienza con un espacio en blanco arbitrario seguido de #también podría tratarse como un comentario:

grep -v '^ *#' filename

si el espacio en blanco es solo espacios, o

grep -v '^[  ]#' filename

donde los dos espacios son en realidad un espacio seguido de un carácter de tabulación literal (escriba "control-v tab").

Para todos estos comandos, omita el filenameargumento para leer desde la entrada estándar (por ejemplo, como parte de una tubería).

Keith Thompson
fuente
He agregado una nueva respuesta que se basa en esta respuesta.
Acumenus
Tuve problemas para usar grep de esta manera en Windows. La solución es reemplazar 'por ", por ejemplogrep -v "^#" filename
Serg
14

Lo opuesto a la solución de Raymond:

sed -n '/^#/!p'

"no imprima nada, excepto las líneas que NO comienzan con #"

ata
fuente
9

puedes editar tu archivo directamente con

sed -i '/^#/ d'

Si también desea eliminar las líneas de comentarios que comienzan con algún uso de espacios en blanco

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

Por lo general, desea mantener la primera línea de su script, si es un sha-bang, por lo sedque no debe eliminar las líneas que comienzan con #!. también debería eliminar líneas, que solo contienen un hash pero no texto. ponlo todo junto:

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

Para cumplir con todas las variantes de sed, debe agregar una extensión de respaldo a la -iopción:

sed -i.bak '/^\s*#/ d' $file
rm -Rf $file.bak
rubo77
fuente
1
más 1 para el que el espacio
deepaksingh pawar
7

Puede usar lo siguiente para una solución awk:

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

Esta respuesta se basa en la respuesta anterior de Keith .

egrep -v "^[[:blank:]]*#" debería filtrar las líneas de comentarios.

egrep -v "^[[:blank:]]*(#|$)" debería filtrar tanto los comentarios como las líneas vacías, como suele ser útil.

Para obtener información sobre [:blank:]y otras clases de caracteres, consulte https://en.wikipedia.org/wiki/Regular_expression#Character_classes .

Acumenus
fuente
Suponiendo que su egrepsoporte tenga esa sintaxis; versiones anteriores pueden no.
Keith Thompson el
-3

Aquí está con un bucle para todos los archivos con alguna extensión:

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
Bruno Damas
fuente