wc -L relata um comprimento de linha 8 para um tab-char. bug ou recurso?


12

-Lé uma característica útil wc, ou assim eu pensei. Imprime o comprimento da linha mais longa. Por alguma razão, ele expande um tab-char de um byte para um comprimento de 8.
Existe alguma maneira de definir isso para não "expandir" a guia? e qual pode ser a lógica por trás dessa expansão?

echo -n $'\t' | wc -L

saídas 8

wc (GNU coreutils) 7.4
GNU bash, versão 4.1.5


O -n é ortogonal à pergunta.
usuário desconhecido

Respostas:


11

Não encontro nenhum relatório de bug relacionado a isso e as seguintes linhas no arquivo de origem wc.c

    case '\t':
        linepos += 8 - (linepos % 8);

parece escolher deliberadamente se comportar dessa maneira, provavelmente para dar uma dica da largura necessária para exibir o arquivo na tela.

Uma alternativa rápida pode ser

echo -n $'\t' | tr '\t' ' ' | wc -L

2
Obrigado, Enzo, agora descobri que, embora man wcnão faça menção a esse problema, ele é declarado em info coreutils 'wc invocation'(que 'man' também se refere) ... Além disso, depois de arrastar um pouco mais o google-sphere, achei isso como uma alternativa echo -n $'\t' | expand -t1 | wc -L, que é praticamente o mesmo que a sua alternativa, mas eu o joguei por uma boa medida. E embora o link a seguir seja um recompile wc hack * , pode ser interessante para alguns: suporte a wc para diferentes larguras de guias
Peter.O

1

Normalmente, uma guia é expandida para a próxima posição (divisível por 8) +1 [1, 9, 17, 25, ...]; portanto, se você pedir, você a obtém.

Observe que o -n é irrelevante para a pergunta, mas o $ não é.

echo foo$'\t' | wc -L

retornará 8 também, porque

echo foo$'\t'bar 
foo     bar

Você pode omitir o $, se usar -e para eco:

echo -e '\t' | wc -L
8

Portanto, se você quiser contar o '\ t' como um byte único, omita -e e $:

echo '\t' | wc -L
2

Sim, expandindo guias é bastante comum para um impresso / saída exibida, mas eu achei estranho que um programa que contagens de bytes e palavras contaria 1 personagem como outra coisa senão um personagem ... btw echo '\t'não emitirá uma guia-char (\ x09). Emite uma linha cujo comprimento é 2, ie. a '\'e a 't'. A nova linha não é parte do comprimento de um linha ... (eu tinha um -nno meu exemplo para verificar se wcseria corretamente processar um arquivo que não tem nenhuma fuga de nova linha-char ...)
Peter.O

wc --helpdiz: -L, --max-line-length print the length of the longest line?. Não fala de bytes, mas de comprimentos de linha.
usuário desconhecido

1
Sim, diz "imprima o comprimento da linha mais longa" ... `mas não diz " Assumimos que você deseja que as guias sejam expandidas (não a contagem usual de caracteres, como a maioria das outras funções de comprimento) .. Oh, pelo Dessa forma, expandiremos as guias para 8 espaços, independentemente do que suas paradas específicas estejam definidas. " ... Essa é a armadilha. Não está devidamente documentado.
precisa saber é o seguinte

Como você define a guia? Em Bash? Além disso: as guias não são expandidas para 8 espaços, mas para posições, veja o echo -e foo'\t'bar | wc -Lque resulta em 11, não em 14.
user unknown

Na acima foo\tbarexemplo, wctem assumido guia-pára em um espaçamento nominal de 8 ... O exemplo a seguir mostra como wcignora as configurações de parada de tabulação actualmente activas. Ele gera uma linha para o terminal com 8 colunas de largura / comprimento, e ainda o wcinforma como 11. Este exemplo define paradas de tabulação para cada 6a coluna ...tabs -6; echo 12345678; echo -e "foo\tbar"|tee >(wc -L)
Peter.O

0

A descrição wc -L era ambígua. Retorna a maior largura de exibição. Para controlar a expansão da guia, você pode filtrar expandprimeiro.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.