Para contar linhas com mais de 80 colunas estou, atualmente, usando este comando:
$ git grep -h -c -v '^.\{,80\}$' **/*.{c,h,p{l,y}} \
|awk 'BEGIN { i=0 } { i+=$1 } END { printf ("%d\n", i) }'
44984
Infelizmente, o repositório usa guias para recuar, portanto, o grep
padrão é impreciso. Existe alguma maneira de ter as regex
guias de tratamento na largura padrão de 8 caracteres, como wc -L
acontece?
Para os propósitos desta pergunta, podemos supor que os colaboradores foram disciplinados o suficiente para recuar consistentemente, ou que eles têm git commit
ganchos em vez de disciplina.
Por motivos relacionados ao desempenho, prefiro uma solução que funcione dentro
git-grep(1)
ou talvez outra grep
ferramenta, sem pré-processamento de arquivos .
Pré-processe os arquivos canalizando-os através de
expand
. Oexpand
utilitário expandirá as guias adequadamente (usando as paradas de tabulação padrão a cada 8 caracteres).GNU
wc -L
não trata TABs como 8 caracteres, ele trata TABs como eles seriam exibidos em um terminal com paradas de TAB a cada 8 colunas, então teria uma "largura" variando de 1 a 8 caracteres, dependendo de onde eles são encontrados na linha .wc -L
também considera a largura de exibição de outros caracteres (se eles têm 0, 1 ou 2 colunas de largura) e também processa\f
e\r
"corretamente".Aqui, você pode usar
expand
(que por padrão também assume paradas de tabulação a cada 8 colunas, embora você possa alterá-lo com opções) para expandir essas TABs para espaços:(convertendo os CRs (que quando enviados para um terminal movem o cursor de volta ao início da linha) e FFs (que alguns dispositivos de exibição entendem como quebra de página) para LF para obter o mesmo comportamento que
wc -L
, mas ignorando os outros que de qualquer forma não podemos dizer que influência eles terão na largura da tela).Isso abrange TABs, mas não caracteres de largura simples ou dupla. Observe que a implementação GNU de
expand
atualmente não expande TABs corretamente se houver caracteres de vários bytes (muito menos de largura zero ou largura dupla).Observe também que
./**/*.{c,h,p{l,y}}
, por padrão, ignoraria arquivos ocultos ou arquivos em diretórios ocultos. À medida que a expansão do brace se expande para vários globs, você também obteria erros (fatal withzsh
orbash -O failglob
) se um desses globs não corresponder.Com
zsh
, você usaria./**/*.(c|h|p[ly])(D.)
que é um glob e ondeD
inclui arquivos ocultos e.
restringe a arquivos regulares .Para uma solução que leva em consideração a largura real dos caracteres (supondo que todos os arquivos de texto sejam codificados na codificação de caracteres da localidade), você pode usar:
Observe que, pelo menos em sistemas GNU,
mbswidth()
considera os caracteres de controle como tendo uma largura de-1
e 1 paraexpand()
. Assumimos que nenhum caractere de controle diferente de CR, NL, TAB, FF é encontrado nos arquivos.Se pudermos presumir pelo seu comentário que os caracteres de tabulação aparecerão apenas no início das linhas, podemos contar alternativas para um mínimo de 80 caracteres.
A confusão resultante é a seguinte, com sua
awk
declaração somando as contagens de linhas individuais para fornecer um total geralUma solução com ex (de vi ). Embora lento.
Como o vi é capaz de processar corretamente dados UTF-8:
Ele pode expandir as guias para espaços, contar os caracteres de controle como 1, processar
\r
\t
\f
\v
corretamente e também processar a maioria dos valores UNICODE válidos . Incluindo acentos compostos (NKC) e decompostos (NKD) e caracteres do cirílico, árabe, grego, chinês e muitos outros.Chame o script como: