¿Le leo correctamente si no desea eliminar todas las líneas en blanco, pero solo si son dos o más? Así que no solo líneas en blanco?
Runium
1
Y si se trata de dos o más líneas, ¿se eliminarán realmente todas o solo todas menos una?
Hauke Laging
Respuestas:
42
Solo para eliminar líneas vacías:
sed '/^$/d'
sedestá orientado a líneas, por lo que pensar en términos de "2 o más de un byte particular" funciona, excepto cuando ese byte es una nueva línea. Entonces tienes que pensar en algo que funcione para toda la línea.
sedes capaz de manejar varias líneas a través de su función "espacio de patrón" / "espacio de espera". Pero siento que es demasiado complicado. ;-)
Hauke Laging
Esto no funcionará como se desea si el primer carácter del archivo es una nueva línea.
Chris Down
1
Para que funcione cuando el primer carácter es un carácter de nueva línea (si eso es realmente un requisito), entonces se puede encerrar el comando con una dirección negativa 1!(que coincida con todos, excepto la línea 1), de este modo: sed '1!{/^$/d'}.
Toby Speight
1
@AaronFranke: sí, pero esa es una faceta de cómo los shells de Linux tratan la redirección '>'. El shell mira la línea de comando, ve una redirección '>' de stdout a un archivo, crea ese archivo y solo entonces se ejecuta sed. La creación de un archivo esencialmente eliminará cualquier archivo existente con el mismo nombre. sed '/^&/d' file.txt > otherfile.txttrabajará.
Bruce Ediger
24
No hay necesidad de sed. grephará:
grep .
(es decir grep, SPC, punto, es decir, coincide con cualquier línea que contenga al menos un carácter).
También hay:
tr -s '\n'
(exprima cualquier secuencia de caracteres de nueva línea en uno).
Como señaló Chris, ambos no son equivalentes porque eliminar líneas vacías (como la primera solución anterior y la mayoría de las otras respuestas se centran aquí) no es lo mismo que exprimir secuencias de caracteres de nueva línea como se solicita en el caso donde la primera línea está vacía. solo se necesita un carácter de nueva línea para dejar vacía la primera línea.
Esto no funcionará como se desea si el primer carácter del archivo es una nueva línea: sprunge.us/FLAJ
Chris Down
7
sedno es la mejor herramienta para eso, ya que se basa en líneas y trata \ncomo el carácter de final de línea, esto se complica.Habiendo visto la respuesta de @Bruce Ediger, sedpuede ser la herramienta perfecta para el trabajo, aún así, aquí hay algunas otras opciones:
El separador de registro de entrada, nueva línea por defecto. Esto influye en la idea de Perl de lo que es una "línea". Funciona como la variable RS de awk, incluido el tratamiento de líneas vacías como un terminador si se establece en la cadena nula (una línea vacía no puede contener espacios ni pestañas). Puede configurarlo en una cadena de caracteres múltiples para que coincida con un terminador de caracteres múltiples, o en undef para leer hasta el final del archivo. Establecerlo en "\ n \ n" significa algo ligeramente diferente a establecerlo en "", si el archivo contiene líneas vacías consecutivas. La configuración en "" tratará dos o más líneas vacías consecutivas como una sola línea vacía. Establecer "\ n \ n" supondrá ciegamente que el siguiente carácter de entrada pertenece al siguiente párrafo, incluso si se trata de una nueva línea.
gawk / awk
awk '$1' file.txt
Eso funcionará para el ejemplo publicado, pero como señaló @Stephane Chazelas , también eliminará las líneas cuyo primer campo "parezca" 0. Esto es más robusto:
Para Perl, perl -pe 's/\n+/\n/ file.txtsí, el separador de registro de entrada es irrelevante para este uso.
vonbrand
@vonbrand no, perl -peo perl -netrabajar línea por línea. \n+nunca coincidirá porque solo se aplica en una sola línea. Es por eso que usted necesita alguno de los conjuntos $/o utilizar -0TI sLuRp el archivo de conjunto: perl -0pe 's/\n+/\n/' file.
terdon
6
¿Qué quieres decir con eliminar? eliminar duplicado (muchas líneas en blanco a una) o eliminar todo?
Si desea eliminar duplicados, este es el método que usa sed:
¡La sedparte de esto funciona muy bien! Recomiendo esta como la mejor respuesta.
Akito
2
Para la mayoría de estas respuestas, primero es necesario eliminar los espacios en blanco finales. Al eliminar las líneas nuevas duplicadas, se eliminan todas las líneas en blanco. (Piensa sobre esto).
Interpretado literalmente, el OP quiere que "se eliminen todas las líneas en blanco de un archivo si hay líneas en blanco repetidas".
El usuario típico quiere "eliminar solo las líneas en blanco duplicadas".
Para hacer esto, primero elimine el espacio en blanco al final y canalice a través de cat -s
sed s/[[:space:]]*$// | cat -s
Y, sin embargo, esto no eliminará una línea en blanco inicial o posterior superfluo.
Votado negativamente, pero esto claramente funciona? Sin comentarios ?
mckenzm
1
Te voté por ... ya sabes ... respondiendo la pregunta. =) No puedo creer que la respuesta de Bruce Ediger haya sido votada cuando elimina cada línea en blanco. Si alguien pregunta cómo eliminar líneas en blanco duplicadas, no puedo imaginar ningún escenario en el que eliminar todas las líneas en blanco sea una solución aceptable. Pero lo que sea. Hay una página en el sitio web para sed que cubre esto, por cierto: gnu.org/software/sed/manual/sed.html#cat-_002ds
Todd Walton
2
Si desea mantener una sola línea en blanco para cualquier secuencia dada de líneas en blanco, puede hacer lo siguiente:
Esta es la única respuesta (además cat -s) que realmente cumple exactamente lo que se hizo la pregunta tal como la entiendo. (Y es mejor que cat -sporque puedo usarlo sed -i)
Matthew
-2
Intente sed -e 's#\\n\\n#\\n#g' input.file > output.fileusar /ambos como separador de campo y parte de su expresión regular podría ser el problema.
AFAIK esta respuesta es incorrecta. Te recomiendo que lo elimines.
zuazo
oh, es porque mi archivo contiene muchas líneas nuevas y retornos de carro en realidad. 0x0d0a
miau
2
En realidad, el comando elimina líneas repetidas con el final de línea de Windows. Prueba con echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'. El comando trse traducirá todo \ra \ny luego la comprime todo \na una sola. Entonces, funciona, no estoy seguro de qué hacer con el hecho de que esto se aplica a Windows, no a UNIX.
Respuestas:
Solo para eliminar líneas vacías:
sed
está orientado a líneas, por lo que pensar en términos de "2 o más de un byte particular" funciona, excepto cuando ese byte es una nueva línea. Entonces tienes que pensar en algo que funcione para toda la línea.fuente
sed
es capaz de manejar varias líneas a través de su función "espacio de patrón" / "espacio de espera". Pero siento que es demasiado complicado. ;-)1!
(que coincida con todos, excepto la línea 1), de este modo:sed '1!{/^$/d'}
.sed
. La creación de un archivo esencialmente eliminará cualquier archivo existente con el mismo nombre.sed '/^&/d' file.txt > otherfile.txt
trabajará.No hay necesidad de
sed
.grep
hará:(es decir
grep
, SPC, punto, es decir, coincide con cualquier línea que contenga al menos un carácter).También hay:
(exprima cualquier secuencia de caracteres de nueva línea en uno).
Como señaló Chris, ambos no son equivalentes porque eliminar líneas vacías (como la primera solución anterior y la mayoría de las otras respuestas se centran aquí) no es lo mismo que exprimir secuencias de caracteres de nueva línea como se solicita en el caso donde la primera línea está vacía. solo se necesita un carácter de nueva línea para dejar vacía la primera línea.
fuente
Habiendo visto la respuesta de @Bruce Ediger,sed
no es la mejor herramienta para eso, ya que se basa en líneas y trata\n
como el carácter de final de línea, esto se complica.sed
puede ser la herramienta perfecta para el trabajo, aún así, aquí hay algunas otras opciones:Perl
o
Gracias a @ruakh que me hizo ir y leer esto :
gawk / awk
Eso funcionará para el ejemplo publicado, pero como señaló @Stephane Chazelas , también eliminará las líneas cuyo primer campo "parezca"
0
. Esto es más robusto:fuente
perl -pe 's/\n+/\n/ file.txt
sí, el separador de registro de entrada es irrelevante para este uso.perl -pe
operl -ne
trabajar línea por línea.\n+
nunca coincidirá porque solo se aplica en una sola línea. Es por eso que usted necesita alguno de los conjuntos$/
o utilizar-0
TI sLuRp el archivo de conjunto:perl -0pe 's/\n+/\n/' file
.¿Qué quieres decir con eliminar? eliminar duplicado (muchas líneas en blanco a una) o eliminar todo?
Si desea eliminar duplicados, este es el método que usa sed:
Simula
uniq
comando.La mejor opción es usar
awk
:fuente
sed
parte de esto funciona muy bien! Recomiendo esta como la mejor respuesta.Para la mayoría de estas respuestas, primero es necesario eliminar los espacios en blanco finales. Al eliminar las líneas nuevas duplicadas, se eliminan todas las líneas en blanco. (Piensa sobre esto).
Interpretado literalmente, el OP quiere que "se eliminen todas las líneas en blanco de un archivo si hay líneas en blanco repetidas".
El usuario típico quiere "eliminar solo las líneas en blanco duplicadas".
Para hacer esto, primero elimine el espacio en blanco al final y canalice a través de cat -s
Y, sin embargo, esto no eliminará una línea en blanco inicial o posterior superfluo.
fuente
Si desea mantener una sola línea en blanco para cualquier secuencia dada de líneas en blanco, puede hacer lo siguiente:
fuente
cat -s
) que realmente cumple exactamente lo que se hizo la pregunta tal como la entiendo. (Y es mejor quecat -s
porque puedo usarlosed -i
)Intente
sed -e 's#\\n\\n#\\n#g' input.file > output.file
usar/
ambos como separador de campo y parte de su expresión regular podría ser el problema.fuente
Usa este comando:
fuente
echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'
. El comandotr
se traducirá todo\r
a\n
y luego la comprime todo\n
a una sola. Entonces, funciona, no estoy seguro de qué hacer con el hecho de que esto se aplica a Windows, no a UNIX.