Mi archivo de texto se ve así:
This is one
sentence that is broken.
However this is a good one.
And this
one is
somehow, broken into
many.
Quiero eliminar el carácter de nueva línea al final de cualquier línea seguida de una línea que comience con una letra minúscula.
Entonces esto debería ser:
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.
¿Cómo puedo hacer esto?
Editar: Hay algunas respuestas realmente buenas aquí, pero elegí aceptar la primera que funcionó y fue la más temprana. Muchas gracias a todos!
Respuestas:
tratar
dónde
$NF !~ /\.$/
línea de coincidencia donde el último elemento no termina con un punto,{ printf "%s ",$0
imprima esta línea con un espacio de seguimiento y sin avance de línea,next ; }
buscar la siguiente línea,{print;}
e imprimirlo.Estoy seguro de que habrá una
sed
opción.Nota: esto funcionará con una línea que termina en un punto, sin embargo, la condición en las oraciones que comienzan con mayúscula no se fusionará. Ver la respuesta de Stéphane Chazelas.
fuente
awk 'ORS=$NF~/\.$/?"\n":" "'
Con
awk
:Es decir, no agregue el separador de registros a cada línea (ORS vacío). Pero anteponga un separador de registro antes de la línea actual si no está en la primera línea y la línea actual no comienza con una letra minúscula. De lo contrario, anteponga un carácter de espacio, excepto en la primera línea.
fuente
And thisone issomehow, broken intomany.
, no sé,awk
pero ¿deberían unirse las líneas<space>
además deRS
? ¿O es este error del usuario?En perl:
Técnicamente, quería reemplazar "nueva línea seguida de letra minúscula" por "espacio y esa letra minúscula", que es lo que hace el núcleo del script perl anterior:
input
.input
variable para que sea el resultado de la operación de búsqueda y reemplazo.fuente
perl -0777 -pe 's/\n([a-z])/ $1/g'
y de manera similar se puede hacer con GNU sed comosed -zE 's/\n([a-z])/ \1/g'
(suponiendo que la entrada no tenga caracteres nulos)perl -Mopen=locale -0777 -pe 's/\n(?=[[:lower:]])/ /g'
para que no se limite a letras ASCII.Con
sed
podría usar unN;P;D
ciclo (para tener siempre dos líneas en el espacio del patrón y si el primer carácter después de la nueva línea está en minúscula, reemplace la nueva línea con un espacio) y unt
est - de esa manera después de cadas
sustitución reinicie el ciclo:fuente
N;P;D
ciclo aquí para que no lo repita nuevamente. La diferencia aquí es la mejort
, para verificar si algo fue reemplazado o no, si la prueba es exitosa, entonces saltamos a la parte superior del script, de lo contrario significa que nada fue reemplazado yP;D
se ejecuta. Avísame si aún no está claro.Usando
sed
yfmt
:La secuencia de comandos sed inserta una nueva línea antes de cada línea que comienza con una letra mayúscula (excepto la primera línea de entrada).
sed
La salida de la salida se canalizafmt
para formatear los párrafos resultantes.Alternativamente, use
par
si lo tiene instalado. Es otro formateador de párrafos, pero mucho más capaz quefmt
, con muchas más características y opciones.Tenga en cuenta que habrá una línea en blanco entre cada párrafo. Los párrafos deben estar separados entre sí por al menos una línea en blanco. Sin las líneas en blanco, toda su muestra de entrada se reformatea como un solo párrafo de varias oraciones, por ejemplo:
Si necesita eliminar las líneas en blanco después de
sed
volver a formatear, simplemente vuelva a conectarlo, pero esto eliminará TODAS las líneas en blanco, incluidas las que puedan haber estado en la entrada original. p.ejfuente
Otra forma de hacer esto es:
en donde:
$\
=>ORS
,$/
=>IRS
=\n
,$"
=space
fuente
Python 3
Esta es la misma expresión regular / sustitución que la respuesta de Jeff
fuente