2009-05-28 14 views
27

Tengo un archivo que contiene:¿Cómo puedo reemplazar varias líneas vacías con una sola línea vacía en bash?

something 



something else 

something else again 

Necesito un comando bash, sed/grep nos que producirá la siguiente salida

something 

something else 

something else again 

En otras palabras, tengo que sustituir múltiples líneas en blanco con solo una línea en blanco. grep/sed están basados ​​en línea. Nunca he encontrado una solución de BASH que funcione en patrones de expresiones regulares de varias líneas.

+0

pregunta aclaración rápida: ¿Alguna vez el archivo tiene líneas que * no * están separadas por una línea en blanco? – biggusjimmus

+3

¿Alguna vez tiene líneas duplicadas que no están en blanco? Si no, puedes usar uniq. –

+0

Hay líneas que no están separadas por una línea en blanco. Podría haber líneas duplicadas. –

Respuesta

65

Para los sistemas derivados de BSD (incluyendo GNU):

Sólo se necesita cat con la opción -s que hace que se repite para eliminar vacíos líneas de su producción:

cat -s 

de página del manual: -s --squeeze-blank: suppress repeated empty output lines.

+0

Duh. Solución perfecta. –

+3

por cualquier razón que no funcione para mí 'cat -s file1> file2' – qodeninja

+4

@qodeninja Tampoco funcionó para mí cuando estaba trabajando con archivos con terminaciones de línea de Windows. Tal vez ese podría ser el problema para ti también? Cuando convertí los archivos a las terminaciones de línea de Unix, 'cat -s' funcionó bien para mí. –

1

usar Python:

s = file("filename.txt").read() 
while "\n\n\n" in s: s = s.replace("\n\n\n", "\n\n") 
import sys 
sys.stdout.write(s) 
+0

esto es ineficaz mientras que el bucle – user5672998

-1

súper fácil de hacer con vim. Simplemente abra el archivo y escriba lo siguiente:

:%s/\n\n\n*/\r\r/ 

Eso reducirá todos los bloques de más de 2 líneas nuevas a 2 líneas nuevas. ¡Espero que esto ayude!

6

En realidad, si se reemplaza múltiples saltos de línea con un único salto de línea, la salida sería:

something 
something else 
something else again 

Esto se puede conseguir por:

sed /^$/d FILE 
+0

Esto es correcto, obviamente :) Lo que probablemente OP significa es reemplazar múltiples "en blanco" (tenga en cuenta que esto no es necesariamente vacío, ya que las líneas pueden tener espacio en blanco invisible) con una línea vacía (que a menos que está al principio o al final de la secuencia) significa dos caracteres de línea nueva. – arielf

-2

Puedo entender que es probable que desee para eliminar líneas que solo tienen espacios en blanco.

Eso se puede hacer con:

sed /^[:space:]*$/d FILE 
2

Una solución con awk, que sustituye a varias líneas en blanco con una sola línea en blanco:

awk 'BEGIN{bl=0}/^$/{bl++;if(bl==1)print;else next}/^..*$/{bl=0;print}' myfile 
+0

+1: Las mentes geniales piensan igual: P –

2

lo general, si me parece que no puede SED hacer algo que necesito, me vuelvo a awk:

awk ' 
BEGIN { 
    blank = 0; 
} 

/^[[:blank:]]*$/ { 
    if (!blank) { 
      print; 
    } 
    blank = 1; 
    next; 
} 

{ 
    print; 
    blank = 0; 
}' file 
+0

¡Su solución es más fácil de leer! – mouviciel

12
grep -A1 . <yourfile> | grep -v "^--$" 

Esta solución funciona grep si quiere enviar el siguiente:

entrada

line1 

line2 
line3 


line4 



line5

salida

line1 

line2 
line3 

line4 

line5
+0

Perfecto. ¡Gracias! –

+0

Me gusta, solución muy elegante – duckyflip

+3

Frickin 'brillante, en realidad. No hubiera llegado a esto en un millón de años. Buen trabajo. Una versión _slightly_ más robusta es así por supuesto (para manejar líneas en blanco no vacías): grep -v -A1 '^ [[blank:]] * $' | grep -v '^ - $' –

-4

PIPELINING a | uniq puede ser la solución (si es distinta de las líneas vacías no se dupliquen)

1

Si alguien quiere utilizar perl

perl -00pe0 < file 

hará lo mismo, como cat -s :)

2

Este utiliza marco's solution en varios archivos:

for i in *; do FILE=$(cat -s "$i"); echo "$FILE" > "$i"; done 
9

Acabo de resolver este problema mediante la sed. Incluso si se trata de una cuestión de 7 años de edad, alguien puede puede aquí en busca de ayuda, por lo que escribo mi solución por sed aquí:

sed 'N;/^\n$/D;P;D;' 
+1

Esto funciona bien para mí, y como es sed, puedo usar -i para correcciones in situ. – Kieran

+0

Extraño esto también elimina las últimas 2 líneas para el archivo para mí (en OSX sed) – Nivco

0

Python, la expresión regular:

import re 
import sys 
sys.stdout.write(re.sub('\n{2,}','\n\n', sys.stdin.read())) 
Cuestiones relacionadas