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 29/03/2015, à 16:00

crocefisso

Mon premier script

Bonjour à tous,

Je ne sais pas s'il est approprié de demander de l'aide pour apprendre à programmer dans ce forum, mais je tente mas chance au cas où. Voilà, je n'ai jamais écrit aucun programme ou script de ma vie, mais j'aimerai me lancer. Pour commencer j'aimerai faire un script assez simple pour Ubuntu ayant pour but de modifier automatiquement un fichier de configuration et un fichier .org. Les étapes à suivre par le script seraient les suivantes :

  1. Aller dans un répertoire ou se trouve des fichiers .org à lister
     

cd ~/MonRepertoire/

  2. Lister tous les fichiers .org du répertoire et des sous répertoires
     

find `pwd` -name "*.org"

  3. Copier cette liste dans un fichier temporaire par exemple tmp.txt
     

Aucune idée...

  4. Dans tmp.txt, remplacer toutes les occurences de "/home/hypercroce" par "~" et toutes les occurences de "/home/crocefisso" par "~"
     

Aucune idée...

  5. Ajouter " au début et à la fin de chaque ligne
     

Aucune idée...

  6. Dans le fichier ~/.emacs.d/init.el
     1. effacer le texte se situant entre ";; REFERENCES UPDATE STARTS HERE" et ";; REFERENCES UPDATE ENDS HERE"
     2. copier le contenu de tmp.txt entre ";; REFERENCES UPDATE STARTS HERE" et ";; REFERENCES UPDATE ENDS HERE"
     

Aucune idée...

  7. Dans le fichier ~/MonRepertoire/orgmode.org
     1. effacer le texte se situant entre ";; REFERENCES UPDATE STARTS HERE" et ";; REFERENCES UPDATE ENDS HERE"
     2. copier le contenu de tmp.txt entre ";; REFERENCES UPDATE STARTS HERE" et ";; REFERENCES UPDATE ENDS HERE"
   

Aucune idée...

En plus de savoir quelle commande pourrait réaliser chaque étape, j'aimerai savoir comment assembler toute les étapes dans un script, et une fois ce script fait comment l’exécuter.

J'ai bien conscience, dans demander beaucoup d'un coup, mais je ne sais pas du tout comment aborder le problème. Si connaissez des sites qui pourraient m'orienter je suis aussi preneur. Je vous remercie par avance.

Dernière modification par crocefisso (Le 29/03/2015, à 16:14)

Hors ligne

#2 Le 29/03/2015, à 16:39

pingouinux

Re : Mon premier script

Bonjour,

Pour 1 + 2 + 3 + 5 :

find ~/MonRepertoire/ -name "*.org" | sed 's/^\|$/"/g' >/tmp/tmp.txt

Pour 4 :
Tu n'auras pas à la fois "/home/hypercroce" et "/home/crocefisso", mais uniquement le /home de celui qui a lancé la commande précédente

Pour 6 et 7 :
Les chaînes ";; REFERENCES UPDATE STARTS HERE" et ";; REFERENCES UPDATE ENDS HERE" sont-elles placées sur des lignes différentes ? Seules sur leurs lignes ? Je pense que python serait plus adapté pour ça.

Ajouté :
Sinon, pour 1 + 2 + 3 + 4 + 5 (avec /home/crocefisso) :

find ~/MonRepertoire/ -name "*.org"|sed 's#/home/crocefisso#~#;s/^\|$/"/g' >/tmp/tmp.txt

Dernière modification par pingouinux (Le 29/03/2015, à 17:24)

Hors ligne

#3 Le 29/03/2015, à 20:03

tiramiseb

Re : Mon premier script

Salut,

Pour faire l'ensemble, il est possible que le script suivant soit adapté.

Non testé, fort possible qu'il y ait des erreurs...

#!/bin/sh

find ~/MonRepertoire/ -name "*.org"|sed 's#/home/[^/*]/#~/#;s/^\|$/"/g' >>/tmp/tmp.txt

grep -B10000 ";; REFERENCES UPDATE STARTS HERE" ~/.emacs.d/init.el > /tmp/tmp_init.el.txt
cat /tmp/tmp.txt >> /tmp/tmp_init.el.txt
grep -A10000 ";; REFERENCES UPDATE ENDS HERE" ~/.emacs.d/init.el >> /tmp/tmp_init.el.txt

grep -B10000 ";; REFERENCES UPDATE STARTS HERE" ~/MonRepertoire/orgmode.org > /tmp/tmp_orgmode.org.txt
cat /tmp/tmp.txt >> /tmp/tmp_orgmode.org.txt
grep -A10000 ";; REFERENCES UPDATE ENDS HERE" ~/MonRepertoire/orgmode.org >> /tmp/tmp_orgmode.org.txt

(cela nécessite qu'il n'y ait pas plus de 10000 lignes avant et après le bloc à remplacer)
(ce serait certainement beaucoup plus court avec awk)

Dernière modification par tiramiseb (Le 29/03/2015, à 20:03)

Hors ligne

#4 Le 30/03/2015, à 00:41

crocefisso

Re : Mon premier script

Reboujour,

Un grand merci à pingouinux et tiramiseb! Le code communiqué par tiramiseb fonctionne à la perfection cool ! Je l'ai adapté et commenté comme suit :

#!/bin/sh

rm /tmp/orgmodelist.txt
rm /tmp/.emacs
rm /tmp/orgmode.org

find ~/.../References/ -name "*.org"|sed 's#/home/[^/*]/#~/#;s/^\|$/"/g' >> /tmp/orgmodelist.txt 
# "find ..."	find in References folder and its subfolders all files having a name containing ".org"
# "|"		execute the rest of line as a new command
# sed		???

grep -B10000 ";; REFERENCES UPDATE STARTS HERE" ~/.emacs > /tmp/.emacs
cat /tmp/orgmodelist.txt >> /tmp/.emacs
grep -A10000 ";; REFERENCES UPDATE ENDS HERE" ~/.emacs >> /tmp/.emacs
# "grep -B..."	means that the 10000 lines preceding the line "...STARTS..." (and including it) in ~/.emacs have to be put in /tmp/tmp_emacs.txt
# "cat.."	append orgmodelist.txt to /tmp/tmp_emacs.txt
# "grep -A..."	means that the 10000 lines following the line "...ENDS..." (and including it) in ~/.emacs are appended to /tmp/tmp_emacs.txt

grep -B10000 ";; REFERENCES UPDATE STARTS HERE" ~/.../References/orgmode.org > /tmp/orgmode.org 
cat /tmp/orgmodelist.txt >> /tmp/orgmode.org
grep -A10000 ";; REFERENCES UPDATE ENDS HERE" ~/.../References/orgmode.org >> /tmp/orgmode.org

cp /tmp/.emacs ~/.emacs
cp /tmp/orgmode.org ~/.../References/orgmode.org

Après quelques recherches, j'ai à peu près compris les commandes à l'exception de sed. Après avoir lu plusieurs tutoriels sur sed, je n'arrive toujours pas à comprendre la logique de la ligne (par exemple je ne trouve aucune explication sur # et ; ) :

sed 's#/home/[^/*]/#~/#;s/^\|$/"/g' 

Dernière modification par crocefisso (Le 30/03/2015, à 01:12)

Hors ligne

#5 Le 30/03/2015, à 01:06

crocefisso

Re : Mon premier script

De plus, il y a un détail que je souhaiterai corriger et ne comprenant pas trop cette commande, je ne vois pas trop comment...

La commande :

sed 's#/home/[^/*]/#~/#;s/^\|$/"/g' 

liste les fichiers comme ceci :

...
"/home/hypercroce/Dropbox/.../References/quotes.org"
"/home/hypercroce/Dropbox/.../References/Programming/Scripts/orgmodereferences.org"
...

Alors que je souhaiterai plutôt avoir ceci :

...
"~/Dropbox/.../References/quotes.org"
"~/Dropbox/.../References/Programming/Scripts/orgmodereferences.org"
...

Dernière modification par crocefisso (Le 30/03/2015, à 01:08)

Hors ligne

#6 Le 30/03/2015, à 06:46

pingouinux

Re : Mon premier script

La bonne commande est celle-ci

sed 's#/home/[^/]*/#~/#;s/^\|$/"/g' 

La syntaxe pour remplacer une chaîne avec sed est

sed 'sxchaine1xchaine2x'

x étant un caractère quelconque. On utilise habituellement un /, mais lorsqu'une des chaînes en contient, il faut en prendre un autre, ici un #.
On aurait pu aussi faire ceci, beaucoup moins lisible

sed 's/\/home\/[^/]*\//~\//;s/^\|$/"/g'

Hors ligne

#7 Le 30/03/2015, à 07:25

Hizoka

Re : Mon premier script


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#8 Le 30/03/2015, à 07:39

tiramiseb

Re : Mon premier script

Oups désolé pour l'erreur dans la commande sed smile

Hors ligne

#9 Le 30/03/2015, à 07:41

tiramiseb

Re : Mon premier script

(en tout cas, pour un premier script, même si on t'a donné la solution toute faite tu as bien compris la chose et tu t'es bien documenté, c'est agréable de notre point de vue (plutôt que de demander "pourquoi ci ? pourquoi ça ? et comment ceci ? et comment cela ?" sans même chercher de ton côté), c'est devenu assez rare pour le souligner smile )

Hors ligne

#10 Le 30/03/2015, à 15:26

crocefisso

Re : Mon premier script

pingouinux a écrit :
sed 's#/home/[^/]*/#~/#;s/^\|$/"/g' 

En utilisant cette ligne le script fait maintenant exactement tout ce que je souhaitais big_smile, merci!

Malgré les lectures recommandées par Hizoka (merci!) je n'ai pas réussi à tout comprendre de cette ligne... Mais je crois que j'ai quand même réussi à comprendre une partie :

#sed			[stream editor]
# '			(expressions between ' are only interpreted according to sed interpretation)
#  s			[substitute command]
#   #			Replaces
#    /home/[^/]*/	???
#   #			by
#    ~/			~/
#   #			[end of substitte command]
#  ;			go to next sed command	
#  s			[substitute command]
#   /			Replaces
#    ^			begining
#    \|			or
#    $			ending (of the line)
#   /			by
#    "			"
#   /			[end of substitte command]
#  g			[global flag] and does it globaly (for the whole file)
# '			(expressions between ' are only interpreted according to sed interpretation)

Si je ne me suis pas trompé pour le reste, il ne me reste plus que la partie

 /home/[^/]*/

à comprendre...

tiramiseb a écrit :

(en tout cas, pour un premier script, même si on t'a donné la solution toute faite tu as bien compris la chose et tu t'es bien documenté, c'est agréable de notre point de vue (plutôt que de demander "pourquoi ci ? pourquoi ça ? et comment ceci ? et comment cela ?" sans même chercher de ton côté), c'est devenu assez rare pour le souligner smile )

Merci pour le compliment smile, je pense que ce n'est pas facile de savoir comment et ou chercher l'explication de tel ou tel bout de code quand on fait ses premiers pas (je n'ai jamais étudié la programmation)... Par exemple pour comprendre \| j'ai eu pas mal de mal et pour [^/]*/ je sèche encore...

En tout cas, merci beaucoup pour votre aide, elle m'encourage à vouloir écrire d'autre scripts et même pourquoi pas à faire un programme smile

Dernière modification par crocefisso (Le 30/03/2015, à 15:29)

Hors ligne

#11 Le 30/03/2015, à 15:40

Rufus T. Firefly

Re : Mon premier script

Salut,

C'est là : http://abs.traduc.org/abs-fr/ch18.html
C'est très puissant et très élégant, mais l'aisance dans la manipulation des expressions rationnelles, ça demande de la logique, de la concentration et de l'entraînement. Ne t'étonne pas trop si les premières que tu concocteras donnent quelques fois des résultats un peu surprenants...

Dernière modification par Rufus T. Firefly (Le 30/03/2015, à 15:57)


La provocation est une façon de remettre la réalité sur ses pieds. (Bertolt Brecht)
Il n'y a pas de route royale pour la science et ceux-là seulement ont chance d'arriver à ses sommets lumineux qui ne craignent pas de se fatiguer à gravir ses sentiers escarpés. (Karl Marx)
Il est devenu plus facile de penser la fin du monde que la fin du capitalisme

Hors ligne

#12 Le 30/03/2015, à 15:57

Hizoka

Re : Mon premier script

[^/]*

signifie tout caractère sauf /


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#13 Le 30/03/2015, à 16:03

pingouinux

Re : Mon premier script

crocefisso #10 a écrit :
#    /home/[^/]*/	???

On recherche la chaîne constituée de
/home/
suivie de
zéros ou plus caractères qui ne sont pas des /
suivis de
un /

Hors ligne

#14 Le 30/03/2015, à 16:51

crocefisso

Re : Mon premier script

Je comprends bien la signification de la phrase  /[^/]*/, mais je ne comprends pas quels sont les différents mots qui la composent et ce qu'ils signifient...

Dernière modification par crocefisso (Le 30/03/2015, à 16:55)

Hors ligne

#15 Le 30/03/2015, à 17:07

pingouinux

Re : Mon premier script

[abc] : une occurrence d'un caractère a, b ou c
[^abc] : une occurrence d'un caractère autre que a, b ou c
* : zéro ou plus occurrence du caractère précédent

Hors ligne

#16 Le 30/03/2015, à 17:22

crocefisso

Re : Mon premier script

Ok, super ! Merci beaucoup, je viens de comprendre. Donc le premier et le dernier / de l'expression  /[^/]*/  signifient, se trouvant entre les deux / qui suivent la chaîne /home.
Mais si on sait déjà que la chaîne après /home se situe entre /home/ et le  / qui suit, pourquoi est-il nécessaire de préciser qu'il ne doit pas y avoir de / dans celle-ci ?

Hors ligne

#17 Le 30/03/2015, à 17:35

Hizoka

Re : Mon premier script

Sinon il ne s'arrete pas au 1er / mais au dernier /.

echo "/home/hizoka/Test/b/c/" | sed -n "s@/home/\(.*\)/.*@\1@p"
hizoka/Test/b/c

echo "/home/hizoka/Test/b/c/" | sed -n "s@/home/\([^/]*\).*/@\1@p"
hizoka

KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#18 Le 30/03/2015, à 17:35

pingouinux

Re : Mon premier script

crocefisso a écrit :

Mais si on sait déjà que la chaîne après /home se situe entre /home/ et le  / qui suit, pourquoi est-il nécessaire de préciser qu'il ne doit pas y avoir de / dans celle-ci ?

Un petit exemple devrait éclairer ta lanterne :

$ sed 's#/home/[^/]*/#~/#' <<<"/home/machin/repertoire/sous_repertoire"
~/repertoire/sous_repertoire

$ sed 's#/home/*/#~/#' <<<"/home/machin/repertoire/sous_repertoire"
~/machin/repertoire/sous_repertoire

$ sed 's#/home/.*/#~/#' <<<"/home/machin/repertoire/sous_repertoire"
~/sous_repertoire

Ajout

Dernière modification par pingouinux (Le 30/03/2015, à 17:36)

Hors ligne

#19 Le 30/03/2015, à 18:27

crocefisso

Re : Mon premier script

Bon c'était fastidieux mais je crois que j'ai enfin compris

#   #			Replaces the chain composed by
#    /home	 	/home
#    /[^/]*		followed by All (*) characters between / and / that aren't / ([^/]) 
#    /			folowed by /
#   #			by
#    ~/			~/

Désolé tongue

Hors ligne