OVH Cloud OVH Cloud

utilisation de wc

11 réponses
Avatar
bertrille
J'obtiens un resultat qui contient un maximum de 8 caracteres. Je dois
combler le manque de caractere (s'il y a lieu) avec des zeros en debut
de chaine. Dois-je utiliser wc -c?

10 réponses

1 2
Avatar
Marc Lasson
Bertrille Ethrington a écrit:
J'obtiens un resultat qui contient un maximum de 8 caracteres. Je dois
combler le manque de caractere (s'il y a lieu) avec des zeros en debut
de chaine. Dois-je utiliser wc -c?



si le resultat est un nombre tu peux faire :
x3
printf "%.8d" $x

si le resultat n'est pas un nombre :) :
x=marc
printf "%.*d%s" $[9 - $(echo $x | wc -c)] 0 $x

J'espère avoir bien compris :).

--
Marc.

PS: le titre est ambiguë

Avatar
bertrille
Stephane CHAZELAS wrote in message news:...
Le 25 Aug 2003 09:01:26 -0700, Bertrille Ethrington écrivait :
[...]
Comment devrais-je la modifier pour qu'elle traite un fichier
qui contient des chaines (une par ligne), plutot qu'une chaine
a la fois.


awk '{printf("%" 8 - length ".d%sn", 0, $0)}' fichier.txt


Ca fonctionne bien en bash (ce que je dois utiliser pour de nombreuses
raisons), mais ca donne un espace plutot qu'un zero. Par ailleurs, si
je le met en alias, ca donne:

awk: syntax error at source line 1
context is
{printf(% <<< 8 - length .d%sn, 0, -bash)}
awk: illegal statement at source line 1




L'alias en question est:

alias transa="awk '{printf("%" 8 - length ".d%sn", 0, $0)}' fich1 >
fich2"



Avatar
Stephane CHAZELAS
Le 25 Aug 2003 13:33:02 -0700, Bertrille Ethrington écrivait :
[...]
awk '{printf("%" 8 - length ".d%sn", 0, $0)}' fichier.txt


Ca fonctionne bien en bash (ce que je dois utiliser pour de nombreuses
raisons), mais ca donne une espace plutot qu'un zero


Oups, j'ai pas fait le bon copié collé, c'était :

awk '{printf("%." 8 - length "d%sn", 0, $0)}'

si je le met en alias, ca donne:

awk: syntax error at source line 1
context is
{printf(% <<< 8 - length .d%sn, 0, -bash)}
awk: illegal statement at source line 1




L'alias en question est:

alias transa="awk '{printf("%" 8 - length ".d%sn", 0, $0)}' fich1 >
fich2"


Ben oui, regarde ce qui se passe au niveau des double quotes.

Ça devrait etre

alias transa="awk '{
printf("%." 8 - length "d%sn", 0, $0)
}' fich1 > fich2"

Mais les alias sont à bannir en bash.

transa() {
awk '{printf("%." 8 - length "d%sn", 0, $0)}
' < fich1 > fich2
}

plutot.

--
Stéphane




Avatar
Stephane CHAZELAS
Le 25 Aug 2003 18:13:31 -0700, Bertrille Ethrington écrivait :
[...]
Peux-tu me dire pourquoi on doit les bannir et quelle est la nature de
ce que tu propose en remplacement?


Les alias viennent du shell csh qui lui n'a pas de support pour
les fonctions. Un alias est utilisé pour substituer une commande
par une autre, la substitution se fait à une certain moment de
l'analyse sytaxique et suivant ce que tu vas mettre dedans ça va
plus ou moins bien marcher, quelques fois avec des resultats
très inattendus. Il y a plein de regles toutes plus compliquées
les unes que les autres sur le fonctionnement (regarde par
exemple le "nesting" d'aliases, le cas de l'espace
terminale...).

Le shell csh est une grossière erreur de design à lui tout seul,
les alias en sont un exemple, l'ennui est que csh a été adopté par
de nombreux utilisateurs (à une époque où il était beaucoup plus
user friendly que sh), ce qui fait que certaines de ses
"features" sont devenues populaires et ont été introduites dans
d'autres shells par la suite.

En remplacement, utilise les fonctions, c'est beaucoup plus
cohérent et souple, ça permet plus de choses.

Exemple:

au lieu de:

alias 'll=ls -l'

tu peux faire:

ll() {
ls -l "$@"
}

Bon, là l'avantage n'est pas évident à première vue. Mais, tu
peux faire par exemple:

cll() {
cd "$1"
shift
ls -l "$@"
}

pour une commande qui fait un cd suivi d'un "ls -l", et tu peux
definir une règle de completion distincte pour cette commande
(par exemple qui complete les noms de repertoires pour le
premier argument et les options de ls et les fichiers pour les
suivants).

Les shells zsh et ksh ont aussi un mechanisme qui permet de
definir les fonctions dans des fichiers separés pour les charger
dynamiquement au besoin (et donc eviter d'encombrer la memoire
inutilement), vois du coté de "fpath".

--
Stéphane

Avatar
Marc Lasson
J'ai écrit:

x=marc
printf "%.*d%s" $[9 - $(echo $x | wc -c)] 0 $x


en fait l'utilisation des wc n'est pas utile ici, j'aurai pu
faire :

printf "%.*d%s" $(( 9 - ${#x} )) 0 $x


${#x} : renvoit la longueur de x

--
Marc.
-- eval.sh --
#!/bin/sh
eval $(cat $0 | tail -1)
-- eval.sh --

Avatar
Stephane CHAZELAS
Le Tue, 26 Aug 2003 15:56:25 +0200, Marc Lasson écrivait :
[...]
printf "%.*d%s" $(( 9 - ${#x} )) 0 $x


Ou, encore plus portable:

expr "000000000$x" : '.*(.........)'

--
Stéphane

Avatar
Emmanuel Florac
Dans article ,
disait...

Ou, encore plus portable:

expr "000000000$x" : '.*(.........)'



Toujours aussi fort, et est-ce que ça marche sur Unix v.7 :) ?

--
Quis, quid, ubi, quibus auxiliis, cur, quomodo, quando?

Avatar
Stephane CHAZELAS
Le 26 Aug 2003 13:32:29 -0700, Bertrille Ethrington écrivait :
[...]
Je suis convaincue! Dis-moi ou s'accumulent ses fonctions pour que je
puisse les editer. J'imagine qu'elles ont une espece que permanence
qui va au dela d'une seule session.


Non, à part pour les shells rc/es et dans certaines
circonstances pour ksh (où elles sont transmises par le biais de
l'environnment) mais ça ne fait pas grand sens de transmettre
des définitions de fonctions d'un shell à l'autre.

Comme pour d'autres langages, les fonctions sont des éléments du
"langage" shell. En shell, toute fonction doit etre definie
avant d'etre appelée, une fonction peut etre definie n'importe
comment, l'interpreteur doit juste "interpreter" le code qui
sert à définir la fonction, tu peux très bien faire dans un
script:

fname=toto
if [ 1 -gt 0 ]; then
eval "$fname() { echo toto; }" # definition de la fonction
# en utilisant eval
fi
toto # appel de la fonction

Pour une utilisation au prompt, comme pour les alias, tu les
définis dans le fichier ~/.bashrc pour le shell bash (parce que
l'interpreteur [le shell] va interpreter le fichier ~/.bashrc,
avant d'interpreter les lignes que tu vas taper au prompt).
tu peux bien sur aussi taper les définitions des fonctions au
prompt.

Sinon, si comme je te le conseille, tu optes pour le shell zsh,
tu peux aussi par exemple creer un répertoire ~/.zsh/functions,
rajouter dans ton ~/.zshrc: « fpath=($fpath ~/.zsh/functions) »
et marquer "autoloadables" les fonctions qui y sont définies.

Ainsi, si tu crées un fichier ~/.zsh/functions/mafonction qui
contient « echo hello world », que tu mets
« autoload mafonction » dans ~/.zshrc, tu auras:

~$ whence -f mafonction
mafonction () {
# undefined <= mafonction n'est pas
chargée, elle est juste
marquée "autoload"
builtin autoload -X
}
~$ mafonction
toto
~$ whence -f mafonction <= maintenant, elle est chargée
mafonction () { en mémoire, du fait de l'avoir
echo toto appelée à la ligne au dessus
}

pour illustrer le principe de chargement dynamique dont je
parlais dans mon autre post. zsh vient avec de nombreuses
fonctions déjà définies fort utiles (pour la completion ou
autres).

Voir http://www.zsh.org, voir aussi la page info de zsh très
bien faite.

--
Stéphane

Avatar
bertrille
Stephane CHAZELAS wrote in message news:...
Le Tue, 26 Aug 2003 15:56:25 +0200, Marc Lasson écrivait :
[...]
printf "%.*d%s" $(( 9 - ${#x} )) 0 $x


Ou, encore plus portable:

expr "000000000$x" : '.*(.........)'


quand tu ecrit

expr "000000000$x" : '.*(.........)'

est-ce que ca remplace

${#x}

ou

printf "%.*d%s" $(( 9 - ${#x} )) 0 $x


Avatar
Stephane CHAZELAS
Le 26 Aug 2003 15:55:33 -0700, Bertrille Ethrington écrivait :
[...]
quand tu ecrit

expr "000000000$x" : '.*(.........)'

est-ce que ca remplace

${#x}

ou

printf "%.*d%s" $(( 9 - ${#x} )) 0 $x


Ça prends les 9 derniers caractères de la chaine résultat de la
concaténation de 000000000 (9 zeros) et $x. Donc, ça left-pad
sur 9 caractères avec des zeros. Voir man expr.

--
Stéphane

1 2