Tengo un archivo que contiene texto en párrafos (líneas con texto separado por una o más líneas vacías). Me gustaría invertir el orden de los párrafos (es decir, el último párrafo se convertirá en el primero, ...), preferiblemente usando sed.
Estoy buscando un comando sed que haría a un archivo de párrafos, lo tac
que haría a un archivo de líneas.
fuente
Puede haber una manera de hacer esto
sed
, pero dudo que sea simple. Así es como lo haría en Perl:Esto funciona porque definir el separador de registro de entrada como el carácter nulo (
-00
) le dice a Perl que opere en modo párrafo. La definición de Perl de un párrafo 1 coincide exactamente con su definición.1 Mira debajo del encabezado
Other values for $/
fuente
Si sus párrafos siempre están separados por una sola línea vacía:
Es bastante fácil ver cómo funciona si se rompe en pedazos y ejecutar
sed '/^$/s/^/\x02/' infile
a continuación,sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n
y así sucesivamente ...Si sus párrafos están separados por una o más líneas vacías, p. Ej.
y desea revertir el orden de los párrafos pero preservar el orden de "bloques vacíos", puede leer el archivo dos veces:
primero: convierta los párrafos en líneas simples (eliminando los bloques vacíos intermedios) e inviértalos y
segundo: gire los bloques vacíos en líneas individuales, "indexando" el número de líneas vacías en cada bloque (y eliminando las líneas no vacías),
luego
paste
los resultados y procesan la salida para restaurar nuevas líneas:que salidas:
Si no le importa una línea final adicional en la salida, puede soltar la última
sed
:Estos suponen que la primera y la última línea no están vacías (y no
\x02
,\x03
o\x04
en la entrada).fuente
PUEDES hacerlo con una sola instancia de
sed
; No se necesitan tuberías. Dado quesed
solo hace una pasada a través del documento y dado que la parte del archivo requerida como el comienzo de la salida está al final del archivo, requerirá mantener todo el archivo en la memoria interiorsed
(en el espacio de retención), por lo que puede No escala bien. Pero responde la pregunta exactamente:Si no hay una nueva línea final, esto todavía funciona bien. Si hay una nueva línea final, se suprime en la salida (es decir, no habrá una nueva línea inicial en la salida). Si hay (por ejemplo) 5 líneas nuevas en la entrada, habrá 4 líneas nuevas en la salida.
Se conservan los espacios entre párrafos.
El espacio en blanco en una línea vacía de otra manera NO se trata como un salto de párrafo, pero esa es una característica, no un error. :)
También puede hacer esto como una línea mucho menos legible:
Aunque esto solo funciona con GNU
sed
. (Tenga en cuenta el uso complicado de las referencias inversas para realizars/$/\n/
. Sin esto, no sería una línea literal, ya que contendría una barra diagonal inversa-nueva línea).fuente
G;h
. Puede mencionar algo sobre restricciones de entrada o similar.sed
mano, pero la versión del script definitivamente conserva las brechas entre los párrafos. Acabo de probarlo en tu entrada. ¿Probaste la versión del script?Esto debería preservar el espacio entre párrafos (a la vez que es más legible que
sed
:)) Sin embargo, los accesorios para devnull para una respuesta increíble.fuente