O awk
código a seguir quebra as linhas na coluna 72:
awk -v maxLen=72 '
{
out = sep = ""
for ( i=1; i<=NF; i++ ) {
nextOut = out sep $i
if ( length(nextOut) > maxLen ) {
print out
out = $i
}
else {
out = nextOut
sep = FS
}
}
print out
}
' "$1" > "$2"
input.txt
:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do euismo tempor incididunt ut labore et dolore magna aliqua.
output.txt
:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do euismo
tempor incididunt ut labore et dolore magna aliqua.
O problema é, no entanto, que ele funciona apenas para textos ASCII. Se o texto estiver usando, por exemplo, letras cirílicas, as linhas se tornam muito mais curtas.
input.txt
:
Лорем ипсум долор сит амет, консектетур адиписцинг элит, сед до еусимо темпор инцидидант ют лаборе эт долоре магна аликуа.
output.txt
:
Лорем ипсум долор сит амет, консектетур
адиписцинг элит, сед до еусимо темпор
инцидидант ют лаборе эт долоре магна
аликуа.
Se entendi corretamente, isso é porque awk
conta bytes, não caracteres. Mas como isso pode ser corrigido?
nota técnica: Eu uso awk
o fornecido com o macOS.
Como você disse, sua versão de
awk
parece contar bytes, não caracteres. Para consertar isso, use uma implementação com reconhecimento de caracteres, como GNU Awk ou The One True Awk (conforme atualizado para a segunda edição de The AWK Programming Language ).GNU Awk produz
com sua entrada de exemplo em um idioma UTF-8.
No macOS, ambas as implementações podem ser instaladas usando o Homebrew, embora uma de cada vez (elas entram em conflito uma com a outra):
instala o GNU Awk, enquanto
instala o The One True Awk.
Embora não responda exatamente à sua pergunta, para este caso específico você pode considerar usar o
fold
comando, que tem exatamente este propósito ( "Ajustar texto para caber em uma largura especificada" ). No seu caso:Por padrão, ele conta colunas (= caracteres) em vez de bytes.
Se você precisar oferecer suporte a caracteres não ASCII e texto que não esteja em inglês, também precisará considerar caracteres de largura dupla ou largura zero (como marca de combinação) e a infinidade de caracteres de espaçamento que podem ser encontrados em Unicode, algumas das quais não devem ter linhas quebradas, como o espaço não separável .
Aqui, eu usaria
perl
e seuUnicode::LineBreak
módulo interno.Exemplo:
Se a entrada contiver caracteres TAB, você pode querer alimentar a entrada
expand
primeiro (especificando onde as paradas de tabulação devem estar, se não 8 colunas de distância). Cuidado, nem todasexpand
as implementações suportam caracteres de largura zero ou largura dupla, embora as implementações do IIRC BSD geralmente o façam. Veja tambémcol -b
se a entrada contém caracteres de backspace (como às vezes usado para negrito ou sublinhado).