Ir para o conteúdo
OneKitly

Limpar uma lista colada de uma folha de cálculo ou de um PDF

Publicado a 06/08/2026 · 12 min de leitura · Ferramentas de texto e idioma

Daniel Okonkwo

Daniel OkonkwoProgramador front-end e redator de Tecnologia na OneKitly

Desempenho web · Formatos de ficheiro

Verificado a partir de 4 fontes

Ver perfil
Em resumo

Passe primeiro o trim-lines e depois o remove-blank-lines. A ordem importa porque o remove-blank-lines decide o que está vazio com o .trim() do JavaScript, que trata mesmo U+00A0 (espaço inquebrável) como espaço, mas não toca no texto das linhas que mantém: uma linha «Lyon » sobrevive com os três espaços finais intactos. O trim-lines usa o mesmo .trim() e limpa as duas pontas de cada linha, incluindo um retorno de carro solto. Entre os dois cobrem espaços, tabulações, espaços inquebráveis, espaços finos e a marca de ordem de bytes. Dois carateres escapam-lhes: U+00AD, o hífen condicional que um PDF insere onde partiu uma palavra no fim da linha, e U+200B, o espaço de largura nula. Nenhum é espaço para o JavaScript, pelo que atravessam remove-blank-lines, trim-lines, trailing-whitespace-remover e remove-whitespace sem alteração. Vigie sobretudo o trailing-whitespace-remover: só reconhece o espaço ASCII e a tabulação, portanto sobre a string «x» seguida de um espaço inquebrável não muda nada, e sobre «x» + inquebrável + espaço normal retira o normal e deixa o inquebrável. As quatro ferramentas reescrevem também em silêncio os finais de linha CRLF como quebras simples, o que costuma ser o pretendido, e nenhuma considera quebra de linha um retorno de carro solto. Uma colagem de folha de cálculo traz ainda tabulações entre as células de uma linha: o remove-whitespace com as definições por omissão apagará essas tabulações e colará as suas colunas umas às outras.

Uma colagem transporta carateres invisíveis: espaços inquebráveis, hífenes condicionais, espaços de largura nula, tabulações e CRLF. Quatro ferramentas de limpeza foram passadas por cada um, e usam três definições diferentes de espaço.

O que chega realmente à área de transferência

O texto que vê no ecrã e o texto da área de transferência não são o mesmo objeto. Um PDF não tem linhas nem parágrafos: tem caixas de glifos em coordenadas. Quando seleciona uma coluna de texto e a copia, o leitor reconstrói uma ordem de leitura plausível e insere uma quebra de linha no fim de cada caixa, pelo que uma frase que ocupava três linhas impressas chega em três linhas. Se o compositor partiu uma palavra num desses fins de linha, uns produtores escrevem um hífen verdadeiro e outros U+00AD, o hífen condicional, que se desenha como hífen só se ali cair um corte e como nada nos restantes casos. E como a maioria dos PDF europeus é composta com espaços inquebráveis antes dos dois pontos, dos pontos e vírgulas e das unidades, um documento francês ou italiano entrega-lhe U+00A0 onde juraria haver espaços normais.

Uma colagem de folha de cálculo é mais arrumada, mas não limpa. Excel, Numbers e Google Sheets colocam todos uma tabulação entre as células de uma linha e uma quebra de linha entre linhas, e no Windows essa quebra é um CRLF: um retorno de carro seguido de um avanço de linha, dois carateres onde vê um. Apague um bloco de linhas no meio de uma seleção e muitas vezes copia também as linhas vazias, que chegam como linhas contendo apenas tabulações. É essa a forma para a qual as ferramentas desta página foram feitas: uma lista em que as linhas úteis estão separadas por linhas que só contêm carateres invisíveis, e em que algumas linhas úteis carregam carateres invisíveis próprios numa das pontas ou nas duas.

Quatro ferramentas, três definições de espaço

O remove-blank-lines e o trim-lines chamam ambos o .trim() do JavaScript. A linguagem define o que isso remove como WhiteSpace mais LineTerminator, e WhiteSpace inclui todos os carateres da categoria Unicode Space_Separator — onde vivem U+00A0, U+2009 (espaço fino) e U+202F (espaço fino inquebrável) — mais a marca de ordem de bytes U+FEFF. Coloque cada um desses carateres sozinho numa linha e passe pelo remove-blank-lines: a linha desaparece. O remove-whitespace usa a classe de expressão regular \s, que designa o mesmo conjunto. Três das quatro ferramentas concordam, portanto, sobre o espaço inquebrável, e concordam com o que quem lê esperaria.

O trailing-whitespace-remover não. O seu padrão é uma sequência de espaço ASCII ou tabulação ancorada ao fim da linha, e mais nada conta. Alimentado com a string x seguida de um espaço inquebrável, devolve a string inalterada. Alimentado com x seguido de um inquebrável e depois de um espaço normal, retira o normal e devolve x mais o inquebrável: visualmente não encurtou nada, e continua a não ser igual a x. Não é uma diferença cosmética. Se limpa uma lista antes de lhe tirar duplicados, é esse espaço inquebrável sobrevivente que mantém separados dois nomes de cidade idênticos.

Os dois carateres que nenhuma destas ferramentas remove

U+00AD, o hífen condicional, e U+200B, o espaço de largura nula, não são espaços para o JavaScript. A classe de expressão regular \s não os reconhece e o .trim() não os remove, o que foi verificado diretamente em vez de assumido. Assim, uma linha que contenha apenas um hífen condicional sobrevive ao remove-blank-lines e parece, na caixa de saída, exatamente uma linha vazia que a ferramenta se recusou a apagar. A palavra «cooperativas» copiada de um PDF com hifenização, com um hífen condicional entre «co» e «operativas», sai idêntica das quatro ferramentas — e nunca corresponderá à string «cooperativas» em nenhuma pesquisa que faça depois.

Há uma única ferramenta neste site que os apaga mesmo, e a troca é má para cinco das nossas seis línguas. O remove-non-ascii retira todo o carácter acima de U+007F, o que leva de facto o hífen condicional, o espaço de largura nula, o espaço inquebrável e a marca de ordem de bytes. Leva também pura e simplesmente cada letra acentuada em vez de a dobrar: a frase «Les coopératives régionales», passada com um hífen condicional dentro da primeira palavra, saiu «Les coopratives rgionales» — o e acentuado pura e simplesmente desaparecido, não substituído por um sem acento. A via honesta é o find-and-replace com o carácter culpado colado no campo «Localizar», que funciona porque essa ferramenta faz escape ao termo de pesquisa e o compara literalmente. Resta arranjar um exemplar de um carácter invisível, o que é exatamente tão incómodo quanto parece.

Finais de linha, e a única quebra que estas ferramentas não veem

As quatro ferramentas dividem num avanço de linha precedido de um retorno de carro opcional, e depois voltam a juntar o resultado com avanços simples. Isso significa que todas normalizam os finais CRLF do Windows para quebras Unix como efeito secundário, faça o que fizer além disso: cole um bloco de folha de cálculo, passe o remove-blank-lines, e a saída fica um byte mais curta por linha mesmo que nenhuma linha tenha sido removida. É quase sempre o que queria, mas vale a pena saber que aconteceu, porque um ficheiro que depois tenha de voltar a uma ferramenta Windows pode precisar que lhe devolvam os finais.

A quebra que não veem é um retorno de carro solitário, sem avanço de linha atrás — o final de linha do Mac OS clássico até 2001, e o que algumas rotinas de exportação antigas e certos despejos de bases de dados ainda emitem. Perante os três carateres a, retorno de carro, retorno de carro, b, as quatro ferramentas tratam o conjunto como uma só linha e devolvem-no intacto. Nada o avisa. Se uma colagem volta como uma única linha enorme sem quebras visíveis e sem erro, é a primeira coisa a suspeitar, e o remédio é abrir o ficheiro num editor capaz de converter finais de linha antes de o trazer para aqui.

A ordem por que as encadear

trim-lines primeiro, remove-blank-lines depois. A ordem inversa dá o mesmo resultado na maioria das entradas, porque o remove-blank-lines já testa cada linha com .trim() antes de decidir: uma linha de três espaços cai quer tenha aparado antes quer não. Verificado sobre a entrada desarrumada «dois espaços, alpha, dois espaços», depois uma linha só de tabulação, depois «dois espaços, beta, um espaço», depois uma linha vazia, depois «alpha»: ambas as ordens produziram alpha, beta, alpha. A razão para pôr o trim-lines primeiro de qualquer modo é o que vem a seguir. Dê essa mesma entrada ao duplicate-line-finder sem a ter aparado e ele não assinala duplicado nenhum, porque o primeiro alpha leva dois espaços à frente e dois atrás. Dê-lhe a versão aparada e ele assinala alpha.

Duas coisas a não fazer. Não recorra ao remove-whitespace sobre uma colagem de folha de cálculo se não tiver decidido que as colunas podem desaparecer: com a definição por omissão apaga todo o espaço, tabulação e quebra de linha, e a linha de cabeçalho «Nom, tabulação, Ville, tabulação, CA» saiu «NomVilleCA». Ligar «manter quebras de linha» preserva as linhas mas continua a comer as tabulações, portanto as colunas continuam coladas. E não passe o trailing-whitespace-remover à espera de que torne duas linhas comparáveis: retira o espaço ASCII e a tabulação, e mais nada, que era todo o assunto da segunda secção. Quando o objetivo é comparar e não arrumar, é o trim-lines que fecha a diferença.

Uma linha de entrada, passada por cada uma das quatro ferramentas, com a saída que produziram de facto
EntradaO que acontecePorquê
Uma linha de três espaços normais, no remove-blank-linesRemovidaO teste é linha.trim().length > 0, e o .trim() esvazia-a
Uma linha contendo apenas U+00A0, no remove-blank-linesRemovidaO WhiteSpace do ECMAScript cobre toda a categoria Space_Separator
Uma linha contendo apenas U+00AD, no remove-blank-linesMantida, e parece vazia na saídaO hífen condicional é da categoria Cf, um carácter de formatação, não um espaço
x seguido de um U+00A0, no trailing-whitespace-removerDevolvido inalteradoO seu padrão é uma sequência de espaço ASCII ou tabulação no fim da linha, nada mais amplo
x, depois U+00A0, depois um espaço normal, no trailing-whitespace-removerVolta como x seguido de U+00A0A sequência de espaços ASCII para no primeiro carácter fora da classe
O mesmo x mais U+00A0, no trim-linesVolta como xO mesmo .trim() do remove-blank-lines, aplicado ao texto em vez do teste
A linha de cabeçalho Nom, tabulação, Ville, tabulação, CA, no remove-whitespaceNomVilleCA — as colunas desapareceramUma tabulação é espaço, e «manter quebras de linha» só poupa a quebra de linha
a, retorno de carro, retorno de carro, b — em qualquer das quatroTratado como uma só linha, devolvido intactoTodas dividem num avanço de linha precedido de um retorno de carro opcional
Remover linhas em brancoElimine todas as linhas vazias ou só com espaços.Experimentar a ferramenta

Perguntas frequentes

Porque é que a minha lista continua com linhas de aspeto vazio depois do remove-blank-lines?
É quase de certeza um espaço de largura nula (U+200B) ou um hífen condicional (U+00AD) sozinho na linha. Nenhum é espaço para o JavaScript, portanto o teste da ferramenta — sobra alguma coisa depois do .trim()? — responde que sim e a linha fica. Ambos foram passados pela ferramenta para o confirmar. Um espaço inquebrável ou um espaço fino sozinhos teriam sido removidos, logo a linha sobrevivente não é um desses. Para identificar o carácter sem adivinhar, cole a linha num contador de carateres ou de bytes e veja que a contagem é um e não zero.
Então o trailing-whitespace-remover está avariado?
Faz o que a sua própria descrição anuncia — remover espaços e tabulações no fim da linha — e essa definição estreita é a certa para o seu trabalho habitual: limpar o lixo invisível no fim das linhas de código antes de um commit. As ferramentas de diff e os linters ocupam-se do espaço ASCII e da tabulação; um espaço inquebrável dentro de código é um erro que quer ver, não um que queira apagado em silêncio. O único problema é que o nome se lê como uma promessa geral. Para prosa e para listas coladas de documentos, o trim-lines é a ferramenta de definição ampla, e é a que se deve usar quando duas linhas têm depois de comparar como iguais.
Como me livro dos hífenes condicionais que um PDF meteu no meu texto?
Nenhuma das quatro ferramentas deste artigo o fará. O find-and-replace fará, se conseguir meter um hífen condicional no campo «Localizar»: a ferramenta faz escape ao que escrever e compara-o literalmente, o que foi verificado, portanto colar o carácter funciona e escrever uma descrição dele não. Arranjar um exemplar de um carácter invisível costuma passar por selecionar um vão suspeitosamente largo no texto de origem com as setas e Shift, e copiá-lo. O remove-non-ascii também os remove, mas leva com eles cada letra acentuada sem a substituir: sobre texto francês, espanhol, português, alemão ou italiano destrói mais do que conserta.
Alguma coisa disto envia a minha lista para um servidor?
Não. As quatro transformações são operações de string correntes que correm na página que tem aberta, sobre o texto da caixa, e produzem a saída na mesma página. Nada na natureza do trabalho exige um servidor: dividir nas quebras de linha e testar cada linha são umas poucas linhas de código, e não há dicionário nem modelo a consultar. Aqui isso importa mais do que o habitual, porque as listas que se limpam assim vêm muitas vezes de documentos internos — nomes de clientes, referências de encomendas, mapas de pessoal — e colar uma numa ferramenta que a envia é uma decisão de transferência de dados, não de formatação.
A minha colagem de folha de cálculo mantém as tabulações. Como obtenho um item por linha?
Nenhuma das quatro faz isso, e o remove-whitespace faz mesmo o contrário: apaga as tabulações e solda as células umas às outras, o que foi verificado numa linha de cabeçalho de três colunas que voltou como uma só palavra. Se só queria uma coluna, copie uma única coluna da folha: a colagem não conterá tabulação alguma e o remove-blank-lines mais o trim-lines bastam. Se tem várias colunas e as quer empilhadas uma por linha, essa é outra operação com a sua própria ferramenta, e a resposta honesta é que estas quatro limpam linhas, não partem colunas.

Artigos que podem interessar-lhe

Todos os guias
ExplicaçãoEncontrar duplicados numa lista sem folha de cálculoDuas linhas que parecem idênticas muitas vezes não são. A caixa, um espaço final, um espaço inquebrável e duas codificações diferentes da mesma letra acentuada foram passados pelo detetor de duplicados, e ele não assinalou nenhum em três dos quatro casos.TutorialFiltrar linhas por um padrão sem linha de comandosIsto é o grep para quem não usa grep, com uma diferença importante: a procura é uma subcadeia literal, pelo que uma expressão regular a sério devolve uma caixa vazia e nenhum erro. Cada afirmação foi verificada executando a ferramenta.TutorialLimpar texto desarrumado: a ordem das operações que realmente importaRetirar etiquetas antes de descodificar entidades, aparar antes de desduplicar, colapsar os espaços no fim. Três ordens executadas no Node, um pipeline de nove passos na sequência certa e os caracteres invisíveis — U+00A0, U+200B, U+FEFF — que sobrevivem a qualquer limpeza ingénua.GuiaConverter entre formatos de lista sem perder dados: as regras de aspas que ninguém lêPassar de uma lista com quebras de linha para uma lista com vírgulas é trivial até um item conter uma vírgula. As regras de aspas da RFC 4180, porque um campo CSV pode conter uma quebra de linha, porque as folhas de cálculo europeias usam o ponto e vírgula, e o que um item vazio faz à ida e volta — cada caso executado e impresso.ExplicaçãoDetetar o idioma de um texto e porque os textos curtos falhamMedido, não afirmado: 90 frases curtas reais em seis idiomas, nenhuma recusada e 68 certas — 76%, caindo para 64% abaixo de dezasseis letras. Quatro das respostas erradas voltaram com 100% de confiança.TutorialNumerar as linhas de um texto para uma revisão a várias mãosA numeração começa em 1 e não pode ser posta a 0, o alinhamento faz-se com espaços e não com zeros, e a ferramenta que os remove desfaz oito dos onze separadores sem mexer na indentação. O que continua sem saber fazer é distinguir os seus números dos dela.

Ferramentas relacionadas

Tudo o que se segue descreve o que estas ferramentas fazem hoje, verificado executando as suas próprias transformações sobre as entradas exatas reproduzidas em cada artigo, e não o que uma norma obrigue uma ferramenta de texto a fazer. O tratamento do texto linha a linha não tem autoridade única: o que conta como espaço, se duas linhas acentuadas são ou não a mesma linha, e onde termina um URL dentro de uma frase são decididos de forma diferente por cada programa onde colar texto. Quando uma ferramenta erra num caso, isso é dito com franqueza em vez de contornado. Antes de passar qualquer disto por uma lista que não possa reexportar, passe por uma cópia e compare o número de linhas nas duas pontas.

Fontes

Detetaste um erro neste artigo?