Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 02/04/2020, à 04:08

ar barzh paour

[Résolu] printf serait-il buggé comme cut ?

Bonjour
voir post 3 et 4 print compte les bytes
mauvais alignement ? ou je ne vois pas clair ?

for f in cl*.txt; do     printf "fichier : %-15s    chgt : %s modif : %s\n" $(basename "$f") $(stat -c %z "$f" |cut -d ' ' -f1 ) $(stat -c %y "$f" |cut -d ' ' -f1 ); done
fichier : cle.txt            chgt : 2020-04-02 modif : 2020-04-02
fichier : clé.txt           chgt : 2020-04-02 modif : 2020-04-02

Dernière modification par ar barzh paour (Le 18/02/2022, à 20:16)


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#2 Le 02/04/2020, à 08:28

diesel

Re : [Résolu] printf serait-il buggé comme cut ?

Je pense que la différence vient des "stat" et "cut".

Essaye la même chose en enlevant les "cut" et je pense que tu y trouveras l'espace en trop ou en moins.

Amicalement.

Jean-Marie


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

Hors ligne

#3 Le 02/04/2020, à 09:13

credenhill

Re : [Résolu] printf serait-il buggé comme cut ?

hello
poblème avec les caractères accentués dans le noms, peut-être

Hors ligne

#4 Le 02/04/2020, à 10:09

pingouinux

Re : [Résolu] printf serait-il buggé comme cut ?

Bonjour,
Je penche aussi pour l'explication de credenhill en #3.
C'est printf qui est en cause. Il ne compte pas le nombre de caractères, mais le nombre de bytes.

e => <U0065>     /x65         LATIN SMALL LETTER E
é => <U00E9>     /xc3/xa9     LATIN SMALL LETTER E WITH ACUTE
█ => <U2588>     /xe2/x96/x88 FULL BLOCK

Voici un petit test

$ mon_print() { printf "=%-4s=\n" "$1";}

$ mon_print e
=e   =

$ mon_print é
=é  =

$ mon_print █
=█ =

Hors ligne

#5 Le 02/04/2020, à 14:19

ar barzh paour

Re : [Résolu] printf serait-il buggé comme cut ?

@diesel ,non cut n'est pas en cause ici
j'ai recopier une formule que j'ai utilisée mais qui peut se simplifier , sans utiliser cut et l'on voit la même décalage

for f in cl*.txt; do     printf "fichier : %-15s    chgt : \n" $(basename "$f") ; done
fichier : cle.txt            chgt : 
fichier : clé.txt           chgt : 

(c'est pourquoi j'avais indiqué "buggé comme cut)

mon_print() { printf "=%-4s=\n" "$1";}
for car in  e é █ ; do mon_print "$car" ; done
=e   =
=é  =
=█ =

Dernière modification par ar barzh paour (Le 02/04/2020, à 14:33)


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#6 Le 02/04/2020, à 14:36

pingouinux

Re : [Résolu] printf serait-il buggé comme cut ?

Je viens de vérifier pour cut, il compte aussi les bytes.

info cut a écrit :

‘-b BYTE-LIST’
‘--bytes=BYTE-LIST’
     Select for printing only the bytes in positions listed in
     BYTE-LIST.  Tabs and backspaces are treated like any other
     character; they take up 1 byte.  If an output delimiter is
     specified, (see the description of ‘--output-delimiter’), then
     output that string between ranges of selected bytes.

‘-c CHARACTER-LIST’
‘--characters=CHARACTER-LIST’
     Select for printing only the characters in positions listed in
     CHARACTER-LIST.  The same as ‘-b’ for now, but internationalization
     will change that
.  Tabs and backspaces are treated like any other
     character; they take up 1 character.  If an output delimiter is
     specified, (see the description of ‘--output-delimiter’), then
     output that string between ranges of selected bytes.

Hors ligne

#7 Le 03/04/2020, à 07:39

bruno

Re : [Résolu] printf serait-il buggé comme cut ?

Bonjour,

Le problème est marqué comme résolu mais je ne vois pas la solution wink
Si je reprend l'exemple du #5 :

$ for car in e é €; do printf "%-4s=\n"  "$car"; done
e   =
é  =
€ =

Maintenant si on veut avoir des espacement constants, il faut le faire avec une chaîne qui est constante (par exemple une chaîne vide) :

$ for car in e é €; do printf "%s%-4s=\n"  "$car"; done
e    =
é    =
€    =

Hors ligne

#8 Le 03/04/2020, à 13:01

ar barzh paour

Re : [Résolu] printf serait-il buggé comme cut ?

@bruno
merci , j'ai marqué résolu parce que je pensais qu'il n'y avait pas de solution

bruno a écrit :

Maintenant si on veut avoir des espacement constants, il faut le faire avec une chaîne qui est constante (par exemple une chaîne vide) :

oui effectivement ça marche mais je ne comprends pas la solution , il suffirait ? de mettre espace derrière %s

for car in e é €; do printf "%s fin\n"  "$car"; done
e fin
é fin
€ fin

ce qui contredit mon exemple du post #1

for f in cl*.txt; do printf "%-15s chgt\n" "$f"; done
cle.txt         chgt
clé.txt        chgt

mais en mettant une chaine "vide" c'est OK !

for f in cl*.txt; do printf "%s%-15s chgt\n" $f; done
cle.txt                chgt
clé.txt                chgt

quelle est la longueur obtenue ?

for f in cl*.txt; do ( printf "%-15s chgt\n" "$f" ; var=$(printf "%-15s chgt\n" "$f")  ; echo ${#var} );done
cle.txt         chgt
20
clé.txt        chgt
19
for f in cl*.txt; do ( printf "%s%-15s chgt\n" "$f" ; var=$(printf "%s%-15s chgt\n" "$f")  ; echo ${#var} ) ; done
cle.txt                chgt
27
clé.txt                chgt
27

Dernière modification par ar barzh paour (Le 03/04/2020, à 13:21)


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#9 Le 03/04/2020, à 13:14

bruno

Re : [Résolu] printf serait-il buggé comme cut ?

Dans mon premier retour en #7 la valeur de $car est substituée par %-4s. Donc printf devrait utiliser 4 caractères pour afficher la chaîne contenue dans $car. Si cette chaîne fait moins de 4 caractères, des espaces sont ajoutés.
En fait printf utilise des octets et non des caractères :
    e est codé sur un octet : 0x65, on obtient donc e suivi de trois espaces
    é est codé sur deux octets 0xC3 0x19, on obtient donc é suivi de deux espaces
   € est codé sur trois octets 0xE 0x82 0xAC, on obtient donc € suivi d'une seul espace
Autrement dit quand tu as des chaînes de longueur variable en octets, tu auras en sortie des alignements irréguliers.

Dans ma seconde commande la valeur de $car est substituée par %s et une chaîne vide est substituée par %-4s. Tu auras donc toujours 4 espaces en sortie.
C'est équivalent à :

empty=""
printf "%s%-4s=\n"  "$car" "$empty"

Dernière modification par bruno (Le 03/04/2020, à 13:17)

Hors ligne

#10 Le 03/04/2020, à 13:24

ar barzh paour

Re : [Résolu] printf serait-il buggé comme cut ?

@bruno
ah j'étais en train d'écrire quelque chose sur la longueur des chaines obtenues !!!!!

car="€";empty="";var=$(printf "%s%-4s"  "$car" "$empty")
echo ${#var}
5

Dernière modification par ar barzh paour (Le 03/04/2020, à 13:31)


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#11 Le 03/04/2020, à 13:28

bruno

Re : [Résolu] printf serait-il buggé comme cut ?

Oui j'ai vu wink
J’espère que mon explication est suffisamment claire. (man printf ne l'est pas forcément…)

Hors ligne

#12 Le 03/04/2020, à 13:31

ar barzh paour

Re : [Résolu] printf serait-il buggé comme cut ?

@ bruno
merci pour l'explication!!!!


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#13 Le 18/03/2021, à 18:40

ar barzh paour

Re : [Résolu] printf serait-il buggé comme cut ?

dans un shell un peu plus compliqué cela ne fonctionnait pas
j'ai résolu en calculant le nombre d'octets et le nombre de caractère
f réprésentant un chemin vers un fichier , res une chaîne quelconque

base=$(basename "$f")
#        40 + nb octets         - nb caractères
(( lon=40 + $(wc -c <<<$base) - $(wc -m <<<$base) ))
printf -v var "%s %-${lon}s : ( %s )" "$numero"  "$(basename "$f")" "$res"

exemple

res="info de précision" ; numero="  3"
for f in "général.txt" "general.txt" ; do
base=$(basename "$f")
(( lon=40 + $(wc -c <<<$base) - $(wc -m <<<$base) ))
printf -v var "%s %-${lon}s : ( %s )" "$numero"  "$(basename "$f")" "$res"
echo "$var"
done

le résultat ne présente plus de décalage

3 général.txt                              : ( info de précision )
3 general.txt                              : ( info de précision )

alors qu'avec un longueur fixe lon=40 on obtient

3 général.txt                            : ( info de précision )
3 general.txt                              : ( info de précision )

Dernière modification par ar barzh paour (Le 18/03/2021, à 18:44)


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#14 Le 18/03/2021, à 19:01

Zakhar

Re : [Résolu] printf serait-il buggé comme cut ?

Génial le truc @ar barzh paour !

En effet, le "piège" est classique et printf n'est pas le seul utilitaire GNU a compter uniquement en "octets" (comme si tout codage de caractère était en ASCII ce qui suffit aux américains !) et pas en caractères selon la locale utilisée, qui de plus en plus est UTF-8.


"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)

Hors ligne

#15 Le 18/03/2021, à 21:20

beuguissime

Re : [Résolu] printf serait-il buggé comme cut ?

ar barzh paour a écrit :

dans un shell un peu plus compliqué cela ne fonctionnait pas
j'ai résolu en calculant le nombre d'octets et le nombre de caractère
f réprésentant un chemin vers un fichier , res une chaîne quelconque

base=$(basename "$f")
#        40 + nb octets         - nb caractères
(( lon=40 + $(wc -c <<<$base) - $(wc -m <<<$base) ))
printf -v var "%s %-${lon}s : ( %s )" "$numero"  "$(basename "$f")" "$res"

exemple

res="info de précision" ; numero="  3"
for f in "général.txt" "general.txt" ; do
base=$(basename "$f")
(( lon=40 + $(wc -c <<<$base) - $(wc -m <<<$base) ))
printf -v var "%s %-${lon}s : ( %s )" "$numero"  "$(basename "$f")" "$res"
echo "$var"
done

le résultat ne présente plus de décalage

3 général.txt                              : ( info de précision )
3 general.txt                              : ( info de précision )

alors qu'avec un longueur fixe lon=40 on obtient

3 général.txt                            : ( info de précision )
3 general.txt                              : ( info de précision )

Si, ça fonctionne. Il faut penser à garder un champ vide pour le printf (juste devant $res) :

#!/bin/bash

res="info de précision" ; numero="  3"
for f in "général.txt" "general.txt" ; do
base=$(basename "$f")
lon=29
printf -v var "%s %s%-${lon}s : ( %s )" "$numero"  "$(basename "$f")" "" "$res"
echo "$var"
done

donne

$ bash k.sh
  3 général.txt                              : ( info de précision )
  3 general.txt                              : ( info de précision )

Ou alors je n'ai pas compris ce qui ne fonctionnait pas, étant donnés les messages précédents.

Hors ligne

#16 Le 19/03/2021, à 11:00

ar barzh paour

Re : [Résolu] printf serait-il buggé comme cut ?

@beuguissime
je comprends vite mais il faut m'expliquer longtemps lol lol lol lol

je viens de comprendre comment utiliser ce qu'avait écrit bruno post #7 et #9 en parlant de chaîne vide

printf "%s%-10s:\n" "général" "" ; \
printf "%s%-10s:\n" "general" "" ; \
printf "général%-10s:\n"         ; \
printf "general%-10s:\n"

général          :
general          :
général          :
general          :

!!! à un détail près : on n'obtient pas une chaîne de longueur 10 !!!

en plus ça ne fonctionne pas toujours ?

printf "%s%-10s:\n" "€" "" ; printf "%s%-10s:\n" "€€" ""
€          :
€€          :

Dernière modification par ar barzh paour (Le 19/03/2021, à 11:09)


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#17 Le 19/03/2021, à 11:14

beuguissime

Re : [Résolu] printf serait-il buggé comme cut ?

Oui ça fonctionne si ce qui vient avant la “chaîne vide développée” a le même nombre de caractères. Ce qui était le cas avec ton exemple général/general mais plus avec €/€€. Et là, ta solution est plus robuste. On est d'accord.

Hors ligne

#18 Le 19/03/2021, à 11:23

ar barzh paour

Re : [Résolu] printf serait-il buggé comme cut ?

ok je ne comprenais plus !
en fait la variable "f" est le nom d'un fichier , donc peu de chance pour qu'il y ait le même nombre de caractères


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#19 Le 19/03/2021, à 11:31

beuguissime

Re : [Résolu] printf serait-il buggé comme cut ?

Ah, oui c'est vrai. Comme dans ton exemple, général et general ont le même nombre de caractères, c'était compatible avec la première solution donnée. D'où ma remarque. Mais j'aurais dû, dès hier, écrire que ta solution était plus… générale. big_smile

Hors ligne

#20 Le 19/03/2021, à 11:31

beuguissime

Re : [Résolu] printf serait-il buggé comme cut ?

Ah, oui c'est vrai. Comme dans ton exemple, général et general ont le même nombre de caractères, c'était compatible avec la première solution donnée. D'où ma remarque. Mais j'aurais dû, dès hier, écrire que ta solution était plus… générale. big_smile

Hors ligne

#21 Le 20/03/2021, à 13:14

ar barzh paour

Re : [Résolu] printf serait-il buggé comme cut ?

très bien mon commandant
très très bien mon capitaine


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#22 Le 06/04/2021, à 09:37

Tawal

Re : [Résolu] printf serait-il buggé comme cut ?

Hello,

Merci de cette discussion, elle m'a apporté la solution.

En effet, j'avais du mal à aligner une liste avec des caractères accentués et des cédilles.

PS : Pour le calcul de la longueur du champ, ok pour le nb d'octets avec

nb_octets=$(wc -c <<<"$var")

mais pour le nb de caractères, j'utilise

nb_char=${#var}

Thanks.


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne