
Tenho usado wc -l
para verificar o número de linhas existentes em meus arquivos. Funcionou bem sempre, mas não desta vez.
Tenho 120 arquivos grandes que deveriam ter pelo menos duas linhas em cada um deles. Acabei de fazer alguns trabalhos de edição de texto nesses arquivos para remover e adicionar novas linhas. Eu estava tentando verificar o número final da linha usando wc -l *
normalmente. A saída mostrou que a maioria dos arquivos tinha apenas uma linha.
Abri um dos arquivos (que mostrou pelo resultado do comando que tinha apenas uma linha) vim
e posso ver que tinha exatamente 2 linhas. Saia vim
e verifique novamente usando wc -l
, o número de linhas desse arquivo apareceu como 2.
Alguém tem alguma ideia do que aconteceu aqui? E como posso resolver esse problema em vez de abrir todos os 120 arquivos com vim
?
PS: A linha final dos meus arquivos não estava vazia.
Responder1
A implementação comum do gnu wc
diz
'wc' conta o número de bytes, caracteres, palavras separadas por espaços em branco
e novas linhas em cada ARQUIVO fornecido ou entrada padrão se nenhum for fornecido ou para um ARQUIVO de '-'.
portanto, se não houver nenhum caractere de nova linha final no arquivo, a parte "linhas" dowc
saída será um a menos que o esperado. Por exemplo, o seguinte produzirá 1
printf 'hello\nworld' | wc -l
O OP confirmou em comentários que o vim está relatando a falta da nova linha final. Uma solução simples se todos os arquivos tiverem esse problema é
for f in *
do
echo >> "$f"
done
para anexar uma nova linha a cada arquivo.
Uma maneira de adicionar uma nova linha condicionalmente ao final de todos os arquivos, se eles estiverem faltando, é usar sed.
sed -s -i '$s/$/\n/;P;d' *
usa algumas extensões gnu, -s
para tratar cada arquivo separadamente, -i
para fazer uma edição no local e permitir \n
representar uma nova linha. O próprio programa sed diz que na última linha de cada arquivo acrescenta uma nova linha e, para cada linha, imprime até a primeira nova linha e passa para a próxima linha.
Responder2
Esta não é exatamente uma resposta, mas compartilhando uma micro ferramenta pessoal que uso frequentemente para normalizar arquivos de texto (txtnorm):
#!/usr/bin/perl -spi
our($s);
s/\n\r|\r\n|\n|\r/\n/g; ## normalize \n
s/^(\xFF\xFE|\xFE\xFF|\xEF\xBB\xBF)//; ## remove BOM !
s/(?<=.)\z/\n/; ## ensure newline at eof
if($s){ s/\xC2\xA0/ /g } ## -s non breaking spaces-> " "
txtnorm *.txt
normaliza o fim das linhas, garante novas linhas em eof, remove BOMs e (com -s) pode normalizar espaços ininterruptos.
Certifique-se de usá-lo APENAS em arquivos de texto.