OVH Cloud OVH Cloud

recuperer les variables d'un nom de fichier

17 réponses
Avatar
sleepee
je suis debutant (je decouvre le shell)

j'ai besoin de recuperer les variables a partir d'un nom de fichier

TOTO_<ChannelCode>_<CampaignCode>_<Wave>_YYYY-MM-DD_HHMMSS.dat

(par example TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat)

$Channelcode
$CampaignCode
$Wave
$Date

merci

10 réponses

1 2
Avatar
Stephane Chazelas
2004-12-7, 07:16(-08), sleepee:
je suis debutant (je decouvre le shell)

j'ai besoin de recuperer les variables a partir d'un nom de fichier

TOTO_<ChannelCode>_<CampaignCode>_<Wave>_YYYY-MM-DD_HHMMSS.dat

(par example TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat)

$Channelcode
$CampaignCode
$Wave
$Date
[...]


Question repondue dans comp.unix.shell

--
Stephane

Avatar
Greg
je suis debutant (je decouvre le shell)

j'ai besoin de recuperer les variables a partir d'un nom de fichier

TOTO_<ChannelCode>_<CampaignCode>_<Wave>_YYYY-MM-DD_HHMMSS.dat

(par example TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat)

$Channelcode
$CampaignCode
$Wave
$Date

merci


fic=TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat
Channelcode=`echo $fic | cut -d'_' -f2`
CampaignCode=`echo $fic | cut -d'_' -f3`
Wave=`echo $fic | cut -d'_' -f4`
Date=`echo $fic | cut -d'_' -f5`

Avatar
Stephane Chazelas
2004-12-07, 20:08(+01), Greg:
[...]
fic=TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat
Channelcode=`echo $fic | cut -d'_' -f2`
CampaignCode=`echo $fic | cut -d'_' -f3`
Wave=`echo $fic | cut -d'_' -f4`
Date=`echo $fic | cut -d'_' -f5`


Waouh!, 11 forks, 4 (au moins) execs. Sans compter que suivant
les valeurs de fic, ca peut donner des resultats completement
incoherents voire prendre toutes les resources de la machines et
faire enormement d'acces disque, qui dit mieux?

Sur comp.unix.shell, j'avais proposé:

IFS=_
set -f
set x $fic; shift
Channelcode=$2
CampaignCode=$3
Wave=$4
Date=$5

(pas de fork, pas d'exec, pas d'acces disque et pas de resultat
incoherent).

--
Stephane

Avatar
gregg
Stephane Chazelas wrote:
2004-12-07, 20:08(+01), Greg:
[...]

fic=TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat
Channelcode=`echo $fic | cut -d'_' -f2`
CampaignCode=`echo $fic | cut -d'_' -f3`
Wave=`echo $fic | cut -d'_' -f4`
Date=`echo $fic | cut -d'_' -f5`



Waouh!, 11 forks, 4 (au moins) execs.


Comment comptez-vous ?

Sans compter que suivant
les valeurs de fic, ca peut donner des resultats completement
incoherents voire prendre toutes les resources de la machines et


Pourquoi toutes les ressources ?
(vous voulez dire en temps CPU, à cause du parcours que fait cut ??)

faire enormement d'acces disque, qui dit mieux?


Accès disque ?

(j'essaie d'avoir une notion plus précise du comportement du shell, je
profite un peu de votre réponse ;-)


Avatar
Stephane Chazelas
2004-12-08, 09:54(+01), gregg:
Stephane Chazelas wrote:
2004-12-07, 20:08(+01), Greg:
[...]

fic=TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat
Channelcode=`echo $fic | cut -d'_' -f2`
CampaignCode=`echo $fic | cut -d'_' -f3`
Wave=`echo $fic | cut -d'_' -f4`
Date=`echo $fic | cut -d'_' -f5`



Waouh!, 11 forks, 4 (au moins) execs.


Comment comptez-vous ?


Je me suis pas embeter, j'ai laisser strace compter. Faut dire
que j'ai utilisé bash qui n'optimise pas beaucoup. En gros, faut
compter un fork pour `...` (parce que ca necessesite un pipe) et
deux forks pour ... | ...

Ensuite, 1 exec par cut (plus un exec par echo sur les vieux
shell).


Sans compter que suivant
les valeurs de fic, ca peut donner des resultats completement
incoherents voire prendre toutes les resources de la machines et


Pourquoi toutes les ressources ?
(vous voulez dire en temps CPU, à cause du parcours que fait cut ??)

faire enormement d'acces disque, qui dit mieux?


Accès disque ?
[...]


En fait, j'essaie de sensibiliser les gens sur le fait
qu'on ne doit jamais laisser une variable non quotee a moins
qu'on sache ce qu'on fait et pourquoi.

Si fic est TOTO_SMS_CAMPAIGN*SYSTEM_12_2004-12-07_120000.dat, le
shell va lister le repertoire courant (parce qu'il essaie de
trouver un truc qui matche a cause de l'etoile).

Si: TOTO_SMS_ * CAMPAIGN SYSTEM * _12_2004-12-07_120000.dat, c'est
encore pire.

Si:

/*/*/*/../../*/*/*...TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat

la, ca commence a etre dangereux

Il y a des problemes avec echo aussi qui ne gere pas bien les
backslashes et les arguments qui commencent par "-" (faut
utiliser printf a la place).

printf '%sn' "$fic" | cut ...
est deja un peu mieux.

Probleme avec la facon de traiter le problem car il n'a pas ete
dit que les noms des fichiers ne pouvaient pas contenir de sauts
de lignes.

--
Stephane



Avatar
Greg
2004-12-07, 20:08(+01), Greg:
[...]

fic=TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat
Channelcode=`echo $fic | cut -d'_' -f2`
CampaignCode=`echo $fic | cut -d'_' -f3`
Wave=`echo $fic | cut -d'_' -f4`
Date=`echo $fic | cut -d'_' -f5`



Waouh!, 11 forks, 4 (au moins) execs. Sans compter que suivant
les valeurs de fic, ca peut donner des resultats completement
incoherents voire prendre toutes les resources de la machines et
faire enormement d'acces disque, qui dit mieux?

Sur comp.unix.shell, j'avais proposé:

IFS=_
set -f
set x $fic; shift
Channelcode=$2
CampaignCode=$3
Wave=$4
Date=$5

(pas de fork, pas d'exec, pas d'acces disque et pas de resultat
incoherent).

Je ne pense pas que mon script mette à plat un PC (même mon vieux 166MX) !

Par contre, le tiens m'interesse:
- en quoi est il plus générique que celui que celui que je propose (tu
définis le même séparateur que moi et tu prends les mêmes champs que moi )?
- je ne connais pas bien l'instuction set (je sais juste qu'elle agit
sur l'environnement bash), mais son utilisation ne peut elle pas poser
de problèmes (tu suggères de modifier le séparateur de champ IFS !)
- si tu as des billes (site internet notamment) sur l'optimisation des
scripts, je suis preneur ..


Greg


Avatar
drkm
Stephane Chazelas writes:

2004-12-08, 09:54(+01), gregg:

Stephane Chazelas wrote:

2004-12-07, 20:08(+01), Greg:

[...]

fic=TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat
Channelcode=`echo $fic | cut -d'_' -f2`
CampaignCode=`echo $fic | cut -d'_' -f3`
Wave=`echo $fic | cut -d'_' -f4`
Date=`echo $fic | cut -d'_' -f5`


Waouh!, 11 forks, 4 (au moins) execs.


Comment comptez-vous ?


Je me suis pas embeter, j'ai laisser strace compter. Faut dire
que j'ai utilisé bash qui n'optimise pas beaucoup. En gros, faut
compter un fork pour `...` (parce que ca necessesite un pipe) et
deux forks pour ... | ...


Et strace t'en rapporte 11 ?

--drkm




Avatar
Stephane Chazelas
2004-12-09, 23:39(+01), Greg:
[...]
fic=TOTO_SMS_CAMPAIGNSYSTEM_12_2004-12-07_120000.dat
Channelcode=`echo $fic | cut -d'_' -f2`
CampaignCode=`echo $fic | cut -d'_' -f3`
Wave=`echo $fic | cut -d'_' -f4`
Date=`echo $fic | cut -d'_' -f5`
[...]



IFS=_
set -f
set x $fic; shift
Channelcode=$2
CampaignCode=$3
Wave=$4
Date=$5
[...]


Je ne pense pas que mon script mette à plat un PC (même mon vieux 166MX) !



Alors, essaie avec:

fic='/*/*/*/../../../*/*/*/../../../*/*/*/../../../whatever'

Si c'est un Linux, ca peut meme peut-etre crasher ta machine.

Par contre, le tiens m'interesse:
- en quoi est il plus générique que celui que celui que je propose (tu
définis le même séparateur que moi et tu prends les mêmes champs que moi )?


Non, le tiens definit plusieurs separateur (NL le separateur
implicite de ligne de cut et _) et ton code, comme je l'ai deja
dit, va foirer (avec des resultats differents selon le shell
et le systeme) si fic contient des blancs (space, tab, newline),
des wildcards ou des backslashs.

- je ne connais pas bien l'instuction set (je sais juste qu'elle agit
sur l'environnement bash)


Elle permet de positionner les "positional parameters" ($1,
$2...)

set a b
fait en sorte que $1 contiennent "a" et $2 contiennent "b" et $#
contienne 2.

mais son utilisation ne peut elle pas poser
de problèmes


On perd les arguments initiaux du script, mais en principe on
les aura stockés au prealable dans des variables plus parlantes.
$@ etant le seul array de "sh", on utilise ce mechanisme assez
frequemment.

(tu suggères de modifier le séparateur de champ IFS !)


Oui ! Chaque fois que tu utilises une variable non-quotee, il
faut fixer la valeur d'IFS au separateur que l'on veut et
activer/desactiver la filename generation suivant qu'on veuille
ou non que les /wildcards/ soient expanded (set -f), (ce que tu
n'as pas fait), c'est pourquoi il ne faut quasi jamais laisser
une variable non-quotee (mon code etant un exemple des rares cas
ou ca peut etre utile).

- si tu as des billes (site internet notamment) sur l'optimisation des
scripts, je suis preneur ..
[...]


www.shelldorado.com a des exemples pas trop mal faits.

--
Stephane



Avatar
Stephane Chazelas
2004-12-10, 02:34(+01), drkm:
[...]
Waouh!, 11 forks, 4 (au moins) execs.


Comment comptez-vous ?


Je me suis pas embeter, j'ai laisser strace compter. Faut dire
que j'ai utilisé bash qui n'optimise pas beaucoup. En gros, faut
compter un fork pour `...` (parce que ca necessesite un pipe) et
deux forks pour ... | ...


Et strace t'en rapporte 11 ?
[...]


Euh non, 12, c'est moi qui sais pas compter.

12 avec dash, 8 avec zsh, 8 avec pdksh, 8 avec ksh93.

--
Stephane




Avatar
drkm
Stephane Chazelas writes:

2004-12-10, 02:34(+01), drkm:

Et strace t'en rapporte 11 ?


Euh non, 12, c'est moi qui sais pas compter.

12 avec dash, 8 avec zsh, 8 avec pdksh, 8 avec ksh93.


Ce qui est plus cohérent ;-).

--drkm


1 2