Como desdobrar o texto de 80 caracteres

5

Muitos arquivos de texto em torno da Internet são divididos em palavras antes que a linha atinja o 80º caractere. Eu entendo que é desejável por aqueles que usam terminais de 80 caracteres. No entanto, gosto de enviar artigos mais longos para o meu kindle, mas esses arquivos parecem muito ruins. Veja esta imagem:

Divisõesde80caracteressãoclaramentevisíveisquandootextoterminanomeiodalinha.

Minhaperguntaé:Comodesembrulhar/cortaressaslinhas?Ométodo"à mão" está, naturalmente, fora de discussão. EDIT: Vamos esclarecer: estou pedindo script ou outro método que seria possível executar a partir do terminal Linux. bash / ruby / python / perl / awk estão ok.

Além disso, supondo que eu tenha apenas texto sem formatação, o LWN é apenas um exemplo.

    
por Szymon Szydełko 23.06.2013 / 00:15

5 respostas

5

A resposta usando fmt parece ser wrap em vez de desembrulhar .

Em geral, isso pode ser um problema difícil. Por exemplo, distinguir entre linhas adjacentes de texto que são deliberadamente terminadas cedo (por exemplo, pontos de bala) e linhas adjacentes de texto livre requer algum contexto. Distinguindo entre palavras hifenizadas através de linhas e palavras divididas também é difícil.

Uma forma comum de prosa, no entanto, são linhas de texto embrulhadas adjacentes formando um parágrafo separado por uma única nova linha vazia.

Isso pode ser desdobrado usando o seguinte, bastante envolvido sed um forro:

sed -n '/.+/ H; /^$/ { x; s/\n/ /g; s/$/\n/ ; p}'

Alternativamente, você pode preferir um pequeno script python, especialmente se você estiver indo para lidar com algum especial casos:

import sys
paragraph = []

for line in sys.stdin:
    line = line.strip()
    if line:
        paragraph.append(line)
    else:
        print ' '.join(paragraph).replace('  ', ' ')
        paragraph = []
if paragraph:
    print ' '.join(paragraph).replace(' ', ' ')

Se você se encontrar adicionando um invólucro especial, então você gosta de encontre a origem do seu texto enrolado em linha e obtenha em um formulário sem linha.

    
por 17.10.2016 / 23:36
1

Casos especiais, como Att Righ disse

Eu encontrei esta pergunta porque eu queria "desembrulhar" a saída do programa fortune , que irritantemente nem é padronizado - alguns cookies da sorte são embalados em 78 caracteres, outros em 77, 76 ou até 75. < br> Meu script tenta determinar se uma nova linha foi inserida propositadamente ou por causa do limite de comprimento, determinando se a linha violaria o limite de comprimento se não tivesse sido quebrada neste exato comprimento (ou seja, se seria muito longo se também incluiu a primeira palavra da próxima linha). Como um efeito colateral útil, se a próxima linha começar com espaço em branco, a primeira palavra (separada por espaço em branco) é a sequência vazia, portanto os parágrafos recuados nunca são mesclados na linha acima deles.

#!/usr/bin/python3

import sys
import fileinput

lines = list(fileinput.input())
lines = [l.strip('\r\n') for l in lines]

for i, l in enumerate(lines):
    # We need to account for 8-char-wide tabulators when calculating our line
    # length, but still want to print the original \t characters verbatim
    sanitized_line = l.replace('\t', ' '*8)

    # Is there a next line?
    if i+1 < len(lines):
        sanitized_next_line = lines[i+1].replace('\t', ' '*8)
    else:
        sanitized_next_line = ''

    next_line_first_word = sanitized_next_line.split(' ', 1)[0]

    if next_line_first_word != '':
        extended_line = sanitized_line + ' ' + next_line_first_word
    else:
        extended_line = sanitized_line

    if len(sanitized_line) <= 78 and len(extended_line) > 74:
        # This line was wrapped due to 78-char limit => unwrap it!
        sys.stdout.write(l + ' ')
    else:
        sys.stdout.write(l + '\n')
    
por 24.05.2017 / 12:55
1

Acabei de encontrar este post enquanto procurava uma maneira de fazer isso com o sed. Aqui está o meu script de shell que tenho usado para a maioria da minha revelação:

# unwrap text with linebreaks in paragraphs and blank lines between paragraphs
# This script reads stdin and writes stdout
# cat is used to read stdin into a here-string so that lnum may be printed at the end, outside of the loop

oline=""
lnum=0

while read aline
do
    lnum=$((++lnum))
    # check for probable blank line by its length, end of paragraph
    if [ ${#aline} -lt 3 ]
        then
        # output concatenated line
        echo "$oline"
        # output blank line
        echo ""
        # prepare for the next paragraph
        oline=""
    else
        # otherwise add it to the unwrapped line
        oline=$(echo $oline|tr -d '\n'|tr -d '\r')
        oline="$oline $aline"
    fi
done <<< "$(cat)"

echo "$lnum"
exit 0
    
por 24.07.2017 / 23:07
1

Eu tive o mesmo problema - enviar arquivos de texto simples contendo feeds de linha dura dentro do corpo de um parágrafo com 80 caracteres ... e esses arquivos parecem terríveis em dispositivos que estão (a) fazendo sua própria quebra de linha e ( b) envolvendo em uma largura menor que 80 ... ou seja, as divisões de 80 caracteres são claramente visíveis onde o texto termina no meio da linha.

Como desembrulhar essas linhas?

Use a ferramenta de linha de comando unix 'fmt', como sugerido por Raúl Salinas-Monteagudo. Altere o comprimento da linha (-w ##) para um número útil. Você poderia tentar 65 ou 55, ou, tente 1111 ou maior.

Exemplo:

Este arquivo do escritório do clima ( link ) contém um feed de linha rígido incorporado ao corpo de um parágrafo. Eu quero feeds de linha apenas no final do parágrafo. Piping a saída para 'fmt-w 1111' (para parágrafos com menos de 1111 caracteres de comprimento) cuida do problema:

/usr/local/bin/w3m -dump 'https://forecast.weather.gov/product.php?site=NWS&issuedby=AT&product=TWO&format=txt&version=1&glossary=0' | sed -n '/TWOAT/,/Forecaster/p' | fmt -w 1111

.

Altera a aparência disso:

The National Hurricane Center is issuing advisories on
Tropical Storm Beryl, located a couple of hundred miles
east of the Lesser Antilles, and on Tropical Storm
Chris, located more than one hundred miles south of the
North Carolina Outer Banks.

Tropical cyclone formation is not expected during the
next 5 days.

para isso:

The National Hurricane Center is issuing advisories on Tropical Storm Beryl, located a couple of hundred miles east of the Lesser Antilles, and on Tropical Storm Chris, located more than one hundred miles south of the North Carolina Outer Banks.

Tropical cyclone formation is not expected during the next 5 days.
    
por 09.07.2018 / 01:33
-2

Acho que exatamente o que você quer é feito por um simples:

fmt -w 80 < input > output
    
por 06.11.2015 / 16:55