Reemplazar varias líneas en blanco con una sola línea en blanco en vim / sed

42

La pregunta más o menos lo dice todo. Soy consciente de que /^$/deliminará todas las líneas en blanco, pero no puedo ver cómo decir 'reemplazar dos o más líneas en blanco con una sola línea en blanco'

¿Algunas ideas?

Andrew Bolster
fuente

Respuestas:

48

Si no está disparando vim o sed para algún otro uso, cat realmente tiene una manera fácil de contraer varias líneas en blanco, solo use cat -s.

Si ya estaba en vim y deseaba quedarse allí, podría hacer esto con la búsqueda interna y reemplazarlo emitiendo: :%s!\n\n\n\+!^M^M!g(El ^ M es la representación visual de una nueva línea, puede ingresar presionando Ctrl+ vEnter), o guardar el tecleando simplemente por los bombardeos a cabo al gato: :%!cat -s.

Caleb
fuente
wow, no conocía la -sopción de cat: solo una nota histórica, no está en POSIX, pero parece estar disponible en BSD y GNU cat.
maxschlepzig
2
Marcado como 'ganador' para el :%!cat -s. ¡Aprende algo GNnew todos los días!
Andrew Bolster
3
Creo que también puedes usar \ r en lugar de ^ M así:%s!\n\n\n\+!\r\r!g
Niko Bellic
Necesitaba esto hoy. ¡Gracias Caleb! :)
Dɑvïd
19

Use \npara indicar una nueva línea en el patrón de búsqueda. Use Ctrl+ Men el texto de reemplazo, o una referencia inversa. Ver :help patterny :help sub-replace-special(vinculado desde :help :s).

%s/\(\n\n\)\n\+/\1/
Gilles 'SO- deja de ser malvado'
fuente
¿Puede explicar cómo funciona el patrón de búsqueda?
Sagar Jain
Requisito @sjmp: reemplace dos o más líneas en blanco con una sola línea en blanco. Implementación: reemplace tres o más líneas nuevas consecutivas con solo dos líneas nuevas. Consulte el manual para obtener una explicación de las construcciones utilizadas en el comando.
Gilles 'SO- deja de ser malvado'
Pero, ¿por qué necesita usar un grupo cuando su contenido es fijo?
Sabuncu
@Sabuncu No necesita usar un grupo. Pero, ¿por qué no usar un grupo? Aquí, utilicé un grupo porque no puede copiar y pegar un comando con una nueva línea en el texto de reemplazo: debe insertar un carácter literal Ctrl + M, \nno funciona en el texto de reemplazo.
Gilles 'SO- deja de ser malvado'
Ahora entiendo, gracias por tomarse el tiempo para responder.
Sabuncu
6

Si en Vim, solo haz esto:

:%!cat -s
coanor
fuente
2
Es posible que desee agregar un pequeño detalle sobre cómo funciona esto, incluso si es solo una cita de la manpágina.
jasonwryan
No funcionó en Windows 7
user674669
0

Usando Perl:

perl -00 -pe ''

-00 la opción de línea de comando activa el modo slurp de párrafo, lo que significa que Perl lee el texto párrafo por párrafo en lugar de línea por línea.

Majid Azimi
fuente
0

Con sed (GNU sed) 4.2.2:

sed -r '
  /^\s*$/ { 
    # blank line
:NEXT
    N # append next line to pattern space - if none, autoprint PS and exit
    s/^\s*$\n^\s*$//g;t NEXT # if 2 blank lines, clear PS and loop to NEXT
  }
  # else, autoprint PS and next/exit
' < $MYFILE
PJ_Finnegan
fuente
-2

Sé que este es un código tonto, pero quería resolver este problema en menos de 10 minutos, y funcionó

for file in /directory/*
do
  originalname=$file
  us='_'
  tempname=$file$us
  echo $originalname
  mv $originalname $tempname
  uniq $tempname $originalname
  rm $tempname
done
Mahmoud Zalt
fuente
1
uniqelimina líneas iguales adyacentes. Que no es lo que OP quiere.
pacholik
@pacholik, dijo claramente "Reemplazar varias líneas en blanco con una sola línea en blanco" ¡NO eliminar las líneas iguales adyacentes!
Mahmoud Zalt
3
Sí, exactamente ...
pacholik