Eliminar líneas en blanco con grep

164

Lo intenté grep -v '^$'en Linux y eso no funcionó. Este archivo proviene de un sistema de archivos de Windows.

nodo ninja
fuente

Respuestas:

300

Intenta lo siguiente:

grep -v -e '^$' foo.txt

La -eopción permite patrones de expresiones regulares para la coincidencia.

Las comillas simples ^$hacen que funcione para Cshell. Otros proyectiles estarán contentos con comillas simples o dobles.

ACTUALIZACIÓN: Esto funciona para mí para un archivo con líneas en blanco o "todos los espacios en blanco" (como las líneas de Windows con terminaciones de línea de estilo "\ r \ n"), mientras que lo anterior solo elimina archivos con líneas en blanco y terminaciones de línea de estilo Unix:

grep -v -e '^[[:space:]]*$' foo.txt
ars
fuente
Ese egrep solo funcionaría para archivos con cero o 1 espacio en la línea, no para archivos con 2 o más espacios. Cambio ? a *.
Ed Morton
44
Esto debería ser grep -E -v, todo después -ese interpreta como el patrón.
jazzpi
66
grep -v -e '^[[:space:]]*$' -e '^#' filele dará todas las líneas no en blanco, sin comentarios en un script o archivo de configuración (o cualquier tipo de archivo que use el carácter hash para comentarios).
palswim
"La -eopción permite patrones de expresiones regulares para la coincidencia". Eso es muy engañoso . -ees una definición (POSIX-) para: This can be used to specify multiple search patterns, or to protect a pattern beginning with a hyphen (-).(del manual ). Grep ya espera una expresión regular (básica) por defecto. Para este patrón, es posible dejar de lado -epor completo: grep -v '^[[:space:]]*$' foo.txt.
Yeti
73

Mantenlo simple.

grep . filename.txt
Frej Connolly
fuente
1
esto me da todas las líneas en el archivo
phuclv
2
@ LưuVĩnhPhúc Debería mostrar todas las líneas del archivo excepto las líneas en blanco.
Frej Connolly
2
Esto funciona para mí en archivos de un sistema basado en Linux pero no en archivos de Windows. Presumiblemente debido a los caracteres de final de línea de Windows.
Estoy votando esto a pesar de que no resuelve el problema del OP de manejar un archivo con terminaciones de línea de Windows, pero como no tengo ese problema, resultó ser la solución perfecta para mí.
David Z
1
Esta es la solución perfecta. Simple y trabajado en Linux.
W00f
30

Utilizar:

$ dos2unix file
$ grep -v "^$" file

O simplemente simplemente awk:

awk 'NF' file

Si no tiene dos2unix, puede usar herramientas como tr :

tr -d '\r' < "$file" > t ; mv t "$file"
ghostdog74
fuente
No puedo encontrar el programa dos2unix. ¿Eso es para Windows? el comando preguntar tampoco funciona.
nodo ninja
¿pedir? No, eso es awk.
iconoclasta
Buen punto sobre la conversión a finales de línea de estilo UNIX; de lo contrario, las expresiones regulares pueden no funcionar como se esperaba. Nada aquí funcionó para mí hasta que convertí los finales de línea.
Ryan H.
16
grep -v "^[[:space:]]*$"

The -v makes it print lines that do not completely match

===Each part explained===
^             match start of line
[[:space:]]   match whitespace- spaces, tabs, carriage returns, etc.
*             previous match (whitespace) may exist from 0 to infinite times
$             match end of line

Ejecutando el código

$ echo "
> hello
>       
> ok" |
> grep -v "^[[:space:]]*$"
hello
ok

Para entender más acerca de cómo / por qué funciona esto, recomiendo leer sobre expresiones regulares. http://www.regular-expressions.info/tutorial.html

Sepero
fuente
2
¿Cómo y por qué funciona esto? Su respuesta sería mucho mejor si pudiera explicarlo. Por ejemplo, su expresión regular coincide con el comienzo de la cadena, luego uno o más espacios utilizando el estándar POSIX y luego el final de la cadena, es decir, con grep -v elimina todas las líneas que son solo espacios. ¿Correcto? ¿Qué sucede si no hay espacios? es simplemente un personaje de nueva línea?
Ben
Como muestra mi ejemplo, incluso solo se elimina una línea vacía (la primera línea). Agregué más información, así que espero que eso ayude. :)
Sepero
3

Prefiero usar egrep, aunque en mi prueba con un archivo genuino con línea en blanco, su enfoque funcionó bien (aunque sin comillas en mi prueba). Esto también funcionó:

egrep -v "^(\r?\n)?$" filename.txt
chryss
fuente
Intenté eso. Las líneas en blanco todavía se muestran. ¿Podría ser esto porque el archivo se hizo en Windows?
nodo ninja
3

Si tiene secuencias de varias líneas en blanco en una fila y solo desea una línea en blanco por secuencia, intente

grep -v "unwantedThing" foo.txt | cat -s

cat -s suprime las líneas de salida vacías repetidas.

Su salida pasaría de

match1



match2

a

match1

match2

Las tres líneas en blanco en la salida original se comprimirían o "apretarían" en una línea en blanco.

Senol Erdogan
fuente
2
awk 'NF' file-with-blank-lines > file-with-no-blank-lines
Tim
fuente
2

Lo mismo que las respuestas anteriores:

grep -v -e '^$' foo.txt

Aquí, grep -esignifica la versión extendida de grep . '^ $' significa que no hay ningún carácter entre ^ (Inicio de línea) y $ (final de línea). '^' y '$' son caracteres regex.

Entonces, el comando grep -vimprimirá todas las líneas que no coinciden con este patrón (sin caracteres entre ^ y $).

De esta forma, se eliminan las líneas en blanco vacías.

Padre mateo
fuente
-eno significa "la versión extendida de grep", ¿quizás te confunden -E? El manual dice claramente que -esolo dice explícitamente que sigue un patrón. Dado que el patrón no comienza con un guión, y de todos modos solo está definiendo un patrón, también podría omitirlo, ya que grep espera de manera predeterminada un patrón de expresión regular: grep -v '^$' foo.txt(no es necesario contar con una funcionalidad de expresión regular extendida). También vale la pena mencionar que esto no elimina las líneas en blanco en el archivo, solo lo que se canaliza a través de la salida. Para ese caso, sed -isería la herramienta adecuada.
Yeti
1

Lo intenté mucho, pero esto parece funcionar (suponiendo \rque te muerda aquí):

printf "\r" | egrep -xv "[[:space:]]*"
mvds
fuente
Eso funciona si reemplazo la primera parte con la salida del archivo.
nodo ninja
0

Usando Perl:

perl -ne 'print if /\S/'

\S significa emparejar caracteres no en blanco.

Majid Azimi
fuente
0

egrep -v "^ \ s \ s +"

egrep ya hace expresiones regulares, y el \ s es un espacio en blanco.

El + duplica el patrón actual.

El ^ es para el comienzo

Jonni2016aa
fuente
0

Utilizar:

grep pattern filename.txt | uniq
baitisj
fuente
uniqreducirá las líneas en blanco adyacentes a una sola línea en blanco, pero no las eliminará por completo. Aún así, me gusta tratar de usar uniqasí. Ordenar primero eliminaría efectivamente todas las líneas en blanco, dejando solo una, pero reorganizar el orden de las líneas puede no ser aceptable.
Zach Young
Buen punto. Esto también masticará líneas repetidas. Supongo que mi solución presenta errores.
baitisj
0

Aquí hay otra forma de eliminar las líneas blancas y las líneas que comienzan con el #signo. Creo que esto es bastante útil para leer archivos de configuración.

[root@localhost ~]# cat /etc/sudoers | egrep -v '^(#|$)'
Defaults    requiretty
Defaults   !visiblepw
Defaults    always_set_home
Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR
LS_COLORS"
root    ALL=(ALL)       ALL
%wheel  ALL=(ALL)       ALL
stack ALL=(ALL) NOPASSWD: ALL
lauc.exon.nod
fuente
0

Es cierto que el uso de grep -v -e '^ $' puede funcionar, sin embargo , no elimina las líneas en blanco que tienen 1 o más espacios . Encontré que la respuesta más fácil y más simple para eliminar líneas en blanco es el uso de awk . Lo siguiente es un poco modificado de los chicos de awk anteriores:

awk 'NF' foo.txt

Pero como esta pregunta es para usar grep, voy a responder lo siguiente:

grep -v '^ *$' foo.txt

Nota : el espacio en blanco entre ^ y *.

O puede usar \ s para representar un espacio en blanco como este:

grep -v '^\s*$' foo.txt
MarcT
fuente