Meu arquivo de texto fica assim:
This is one
sentence that is broken.
However this is a good one.
And this
one is
somehow, broken into
many.
Desejo remover o caractere de nova linha à direita de qualquer linha que seja seguida por uma linha que comece com uma letra minúscula.
Portanto, isso deve ser:
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.
Como posso fazer isso?
Edit: Existem algumas respostas muito boas aqui, mas eu escolhi aceitar a primeira que funcionou e foi a mais antiga. Muito obrigado a todos!
Respostas:
experimentar
Onde
$NF !~ /\.$/
linha de correspondência em que o último elemento não termina com um ponto,{ printf "%s ",$0
imprima esta linha com um espaço de destaque e sem alimentação de linha,next ; }
buscar a próxima linha,{print;}
e imprima.Estou certo de que haverá uma
sed
opção.Nota: isso funcionará com a linha que termina em um ponto; no entanto, a condição nas frases que começam com maiúsculas não será mesclada. Veja a resposta de Stéphane Chazelas.
fonte
awk 'ORS=$NF~/\.$/?"\n":" "'
Com
awk
:Ou seja, não anexe o separador de registros a cada linha (ORS vazio). Mas acrescente um separador de registros antes da linha atual, se não estiver na primeira linha, e a linha atual não começa com uma letra minúscula. Caso contrário, adicione um caractere de espaço, exceto na primeira linha.
fonte
And thisone issomehow, broken intomany.
eu não sei,awk
mas as linhas devem ser unidas<space>
além deRS
? Ou esse erro é do usuário?Em perl:
Tecnicamente, você desejava substituir "nova linha seguida por letra minúscula" por "espaço e essa letra minúscula", que é o que o núcleo do script perl acima faz:
input
.input
variável para ser o resultado da operação de pesquisa e substituição.fonte
perl -0777 -pe 's/\n([a-z])/ $1/g'
e pode igualmente ser feito com o GNU sed comosed -zE 's/\n([a-z])/ \1/g'
(assumindo de entrada não têm caracteres nulos)perl -Mopen=locale -0777 -pe 's/\n(?=[[:lower:]])/ /g'
para que não se limite a letras ASCII.Com
sed
você, você pode usar umN;P;D
ciclo (para sempre ter duas linhas no espaço do padrão e, se o primeiro caractere após a nova linha estiver em minúsculas, substitua a nova linha por um espaço) et
est - assim, após cadas
substituição, você reiniciar o ciclo:fonte
N;P;D
ciclo funciona aqui, para que eu não o revise novamente. A diferença aqui é a melhort
- verificar se algo foi substituído ou não - se o teste for bem-sucedido, ramificaremos para a parte superior do script, caso contrário, isso significa que nada foi substituído eP;D
é executado. Deixe-me saber se ainda não está claro.Usando
sed
efmt
:O script sed insere uma nova linha antes de cada linha que começa com uma letra maiúscula (exceto a primeira linha de entrada).
sed
A saída do é então canalizadafmt
para reformatar os parágrafos resultantes.Como alternativa, use
par
se você o tiver instalado. É outro reformatador de parágrafos, mas muito mais capaz quefmt
, com muito mais recursos e opções.Observe que haverá uma linha em branco entre cada parágrafo. Os parágrafos devem ser separados um do outro por pelo menos uma linha em branco. Sem as linhas em branco, toda a amostra de entrada é reformatada como um único parágrafo com várias frases, por exemplo:
Se você precisar remover as linhas em branco após a reformatação, passe-a
sed
novamente - mas isso removerá TODAS as linhas em branco, incluindo as que estiverem na entrada original. por exemplofonte
Outra maneira de fazer isso é:
em que:
$\
=>ORS
,$/
=>IRS
=\n
,$"
=space
fonte
Python 3
Esta é a mesma regra / substituição que a resposta de Jeff
fonte