wc -L signale une longueur de ligne de 8 pour un tab-char. bug ou fonctionnalité?


12

-Lest une fonctionnalité utile wc, du moins je le pensais. Il imprime la longueur de la ligne la plus longue. Pour une raison quelconque, il développe un tab-char à un octet à une longueur de 8.
Existe-t-il un moyen de définir cela pour ne pas "développer" l'onglet? et quelle pourrait être la raison de cette expansion?

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

les sorties 8

wc (GNU coreutils) 7.4
GNU bash, version 4.1.5


Le -n est orthogonal à la question.
utilisateur inconnu

Réponses:


11

Je ne trouve aucun rapport de bogue lié à cela, et les lignes suivantes dans le fichier source wc.c

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

semblent délibérément choisir de se comporter de cette manière, probablement pour donner une indication de la largeur nécessaire pour afficher le fichier à l'écran.

Une alternative rapide pourrait être

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

2
Merci enzo, j'ai maintenant trouvé que bien qu'il man wcne fasse aucune mention de ce problème, il est indiqué dans info coreutils 'wc invocation'(auquel `` l'homme '' fait également référence) ... Aussi, après avoir parcouru un peu plus la google-sphère, j'ai trouvé cela comme une alternative echo -n $'\t' | expand -t1 | wc -L, qui est à peu près la même que votre alternative, mais je l'ai jeté pour faire bonne mesure .. Et bien que le lien suivant soit un recompilation wc hack * , il peut être intéressant pour certains: support wc pour différentes largeurs de tabulation
Peter.O

1

Normalement, un onglet est développé à la position suivante, (divisible par 8) +1 [1, 9, 17, 25, ...], donc si vous le demandez, vous l'obtenez.

Notez que le -n n'est pas pertinent pour la question, mais pas le $.

echo foo$'\t' | wc -L

renverra 8 aussi, car

echo foo$'\t'bar 
foo     bar

Vous pouvez omettre $, si vous utilisez -e pour écho:

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

Donc, si vous voulez compter le '\ t' comme un seul octet, omettez simplement -e et $:

echo '\t' | wc -L
2

Oui, l'expansion des onglets est assez courante pour une sortie imprimée / affichée, mais j'ai trouvé étrange qu'un programme qui compte des octets et des mots compte 1 caractère comme autre chose que 1 caractère ... btw echo '\t'ne produit pas de tab-char (\ x09). Il sort une ligne dont la longueur est 2, c'est-à-dire. a '\'et a 't'. Une nouvelle ligne n'est pas parte de la longueur d'une ligne ... (j'avais un -ndans mon exemple pour vérifier si wctraiterait correctement un fichier qui n'a pas de caractère de fin de ligne ...)
Peter.O

wc --helpdit: -L, --max-line-length print the length of the longest line?. Il ne s'agit pas d'octets, mais de longueurs de ligne.
utilisateur inconnu

1
Oui, il dit "imprime la longueur de la ligne la plus longue" ... `mais il ne dit pas " Nous supposons que vous voulez que les tabulations soient développées (pas le nombre de caractères habituel, comme la plupart des autres fonctions de longueur) .. Oh, par le Ainsi, nous étendrons les tabulations à 8 espaces, quel que soit le réglage de vos tabulations spécifiques. ... C'est le piège .. Il n'est pas correctement documenté.
Peter.O

Comment définissez-vous l'onglet? Dans Bash? De plus: les tabulations ne sont pas étendues à 8 espaces, mais à des positions, voir echo -e foo'\t'bar | wc -Lce qui donne 11, pas 14.
utilisateur inconnu

Dans l' foo\tbarexemple ci-dessus , wca supposé des taquets de tabulation à un espacement nominal de 8 ... L'exemple suivant montre comment wcignore les paramètres de taquets de tabulation actuellement actifs. Il envoie une ligne au terminal qui est de 8 colonnes de terminal large / longue, mais le wcsignale à 11. Cet exemple définit des tabulations à toutes les 6 colonnes ...tabs -6; echo 12345678; echo -e "foo\tbar"|tee >(wc -L)
Peter.O

0

La description de wc -L était ambiguë. Il renvoie la largeur d'affichage la plus large. Pour contrôler l'expansion des onglets, vous pouvez d'abord filtrer expand.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.