Eu tenho um arquivo que contém texto em parágrafos (linhas com texto separadas por uma ou mais linhas vazias). Gostaria de reverter a ordem dos parágrafos (ou seja, o último parágrafo se tornará o primeiro, ...), de preferência usando sed.
Estou procurando um comando sed que faria com um arquivo de parágrafos, o tac
que faria com um arquivo de linhas.
fonte
Pode haver uma maneira de fazer isso
sed
, mas duvido que seja simples. Aqui está como eu faria isso no Perl:Isso funciona porque a definição do separador de registro de entrada como o caractere nulo (
-00
) indica ao Perl para operar no modo de parágrafo. A definição de parágrafo 1 do Perl corresponde exatamente à sua definição.1 Olhe sob o cabeçalho
Other values for $/
fonte
Se seus parágrafos são sempre separados por uma única linha vazia:
É muito fácil ver como ele funciona se você quebrá-lo em pedaços e executar
sed '/^$/s/^/\x02/' infile
, em seguida,sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n
e assim por diante ...Se seus parágrafos estiverem separados por uma ou mais linhas vazias, por exemplo,
e você deseja reverter a ordem dos parágrafos, mas preservar a ordem dos "blocos vazios", você pode ler o arquivo duas vezes:
1º: transformar parágrafos em linhas únicas (removendo os blocos vazios no meio) e invertê-los e
2º: virar os blocos vazios em linhas únicas, "indexando" o número de linhas vazias em cada bloco (e removendo as linhas não vazias),
depois
paste
os resultados e processe a saída para restaurar novas linhas:quais saídas:
Se você não se importa com uma linha de fuga extra na saída, pode soltar a última
sed
:Eles assumem que a primeira e a última linha não estão vazias (e não
\x02
,\x03
ou\x04
na entrada).fonte
Você pode fazê-lo com uma única instância de
sed
; sem tubos necessários. Comosed
apenas uma pessoa passa pelo documento e como a parte do arquivo necessária no início da saída está no final do arquivo, será necessário reter o arquivo inteiro na memóriased
(no espaço de espera) - para que possa não escala bem. Mas responde exatamente à pergunta:Se não houver uma nova linha à direita, isso ainda funcionará bem. Se houver uma única linha nova à direita, ela será suprimida na saída (ou seja, não haverá uma nova linha à esquerda na saída). Se houver (por exemplo) 5 novas linhas à direita na entrada, haverá quatro novas linhas à saída.
As lacunas entre parágrafos são preservadas.
O espaço em branco em uma linha vazia não é tratado como uma quebra de parágrafo, mas isso é um recurso, não um bug. :)
Você também pode fazer isso como o one-liner muito menos legível:
Embora isso funcione apenas com o GNU
sed
. (Observe o uso complicado das referências anteriores para executars/$/\n/
. Sem isso, não seria uma linha única, pois conteria uma nova barra invertida.)fonte
G;h
. você pode mencionar algo sobre restrições de entrada ou similar.sed
mão, mas a versão do script definitivamente preserva as lacunas entre os parágrafos. Acabei de testar na sua entrada. Você testou a versão do script?Isso deve preservar o espaçamento entre parágrafos (embora seja mais legível que
sed
:)). No entanto, você deve adiantar uma resposta impressionante.fonte