Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 04/04/2007, 22h20   #1
Membre habitué
 
Étudiant
Inscription : janvier 2006
Messages : 501
Détails du profil
Informations personnelles :
Âge : 25

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2006
Messages : 501
Points : 113
Points : 113
Par défaut remplacer un mot dans une ligne

Bonsoir,

J'aimerais stocker des infos dans un fichier, sur chaque ligne les infos sont écrites dans un "meme format", par ex :

Citation:
info11|||info21|||info31
info12|||info22|||info32
etc

et savoir si c'est possible de changer qu'une seule info sur une ligne, par exemple que info31 et non remettre toute la ligne

Merci
++
italiasky est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 23h52   #2
Membre expérimenté
 
Avatar de BlaireauOne
 
Inscription : mars 2007
Messages : 469
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2007
Messages : 469
Points : 576
Points : 576
En shell bash, la seule façon simple qui y ressemble est la suivante :

Code :
1
2
 
sed -i 's/info31/Nouvinfo/' NomDeFichier
Petite question : tu utilises comme délimiteurs de champs "|||" ?
BlaireauOne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2007, 06h32   #3
Membre habitué
 
Étudiant
Inscription : janvier 2006
Messages : 501
Détails du profil
Informations personnelles :
Âge : 25

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2006
Messages : 501
Points : 113
Points : 113
Euh ben justement je me demande quels limititeurs utilisés, les ||| c'est pas recommandé ?

sed ne peut etre utilisé avec une variable au lieu d'un fichier ?
par exemple quand je remplace NomDeFichier par une variable qui contient une certaine ligne du fichier, ca ne fonctionne pas...

Et c'est possible de mettre dans des variables différentes, par ex var1, var2, var3 les infos d'une ligne ?
Il faut utiliser les expressions régulières ?
En php, je sais qu'on aurait pu faire un "explode" pour mettre dans un tableau mais la je pense pas que c'est possible..

merci
++
italiasky est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2007, 11h34   #4
Membre à l'essai
 
Inscription : avril 2007
Messages : 24
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 24
Points : 21
Points : 21
un truc dans ce genre la devrait marcher je pense:
Code :
echo $TaVariable | sed 's/info31/Nouvinfo/' > YourFile
ou

Code :
TaVariable="info11|||info21|||info31"; VariableReceptrice=`echo $TaVariable | sed 's/info31/Nouvinfo/'`; echo $VariableReceptrice
Le reste j'ai pas tout compris, mais a mon avis... tu veux utiliser awk
liodev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2007, 15h08   #5
Membre habitué
 
Étudiant
Inscription : janvier 2006
Messages : 501
Détails du profil
Informations personnelles :
Âge : 25

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2006
Messages : 501
Points : 113
Points : 113
Et bien en fait, pour réexpliquer ce que j'essaie de faire :

-Stocker des informations dans un fichier
-Chaque ligne contient les memes genres d'information (délimité par des caracteres : ||| ou autre...) , ex :
info1|||info2|||info3|||info4
bla1|||bla2|||bla3|||bla4
etc...

et ensuite manipuler ce fichier de données, pour insérer une ligne c'est pas bien compliqué mais ca se complique pour récupérer les infos d'une ligne, par exemple, récuperer dans des varirables les infos d'une meme ligne comme ca :
$var1 contiendra info1
$var2 contiendra info2
$var3 contiendra info3
$var4 contiendra info4
si je veux la 1ere ligne.

Et l'autre problème, c'est pour modifier l'info d'une ligne sans forcément réécrire la ligne entiere, par exemple a la place de info3 de la premiere ligne, mettre "coucou"

Vous voyez ce que je veux dire ?

Pouvez-vous m'expliquer rapidement awk ?
Il me semble que ce serait intéressant de l'utiliser en effet.
italiasky est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2007, 15h42   #6
Rédacteur
 
Inscription : mars 2004
Messages : 1 298
Détails du profil
Informations forums :
Inscription : mars 2004
Messages : 1 298
Points : 1 450
Points : 1 450
en générale 1 seul caractère de délimitation doit suffire, les "outils" unix te permettront de manipuler correctement tes "champs" dans une ligne de cette façon.
ensuite extraitre les variables d'une ligne ne te poserons pas de probleme exemple :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
bash-3.1$ cat toto.txt
velo,ballon,maison
test,aaaa,zzzz,zoo
bash-3.1$
bash-3.1$ ./tt
velo
ballon
maison
 
test
aaaa
zzzz
zoo
et voici le script pour ce resultat :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
#!/bin/sh
while read ligne
do
# le "tr" est la pour changer le caractere separateur en separateur standard unix (le blanc)
 ligne="$(echo "$ligne" | tr -s ',' ' ')"
# typeset -a  "explose " en tableau la ligne (tableau var)
 typeset -a var=($ligne)
pour la liste de tout les membres du tableau
   for i in $(seq 0 $(echo ${#var[*]}))
   do
  # affiche l'ement i du tableau
     echo ${var[$i]}
   done
done < toto.txt
pour changer 1 variable dans une ligne .. sed est parfait.
__________________
Marc
Slackware for ever ......
BASH - KSH ( http://marcg.developpez.com/ksh/ )
MarcG est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2007, 16h26   #7
Membre à l'essai
 
Inscription : avril 2007
Messages : 24
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 24
Points : 21
Points : 21
2 exemple d'utilisation d'awk qui pourraient t'aider si tu veux, c'est un truc qui permet de faire vachement de choses sans trop de difficultés... si on connait un peu

Code :
1
2
$ echo "toto,tata,titi" | awk -F "," '{print $1 " " $2 " " $3}'
toto tata titi
Code :
1
2
$ echo "toto#tata#titi" | awk -F "#" '{print $1 " blabla " $3}'
toto blabla titi
liodev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2007, 19h55   #8
Membre habitué
 
Étudiant
Inscription : janvier 2006
Messages : 501
Détails du profil
Informations personnelles :
Âge : 25

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2006
Messages : 501
Points : 113
Points : 113
Ok merci je vais me débrouiller avec tout ca maintenant alr

++
italiasky est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2007, 22h19   #9
Membre émérite
 
Inscription : mai 2004
Messages : 709
Détails du profil
Informations personnelles :
Localisation : Belgique

Informations forums :
Inscription : mai 2004
Messages : 709
Points : 852
Points : 852
Si tu veux vraiment imiter la fonction explode() de PHP il faut que les champs vides soient assignés comme null dans l'élément du tableau.
un:deux::quatre explosé sur : doit retourner
a[0] => un
a[1] => deux
a[2] =>
a[3] => quatre


Le remplacement des : par des espaces va masquer les champs vides:
un:deux::quatre devient un deux quatre (avec deux espaces entre 2 et 4). Du coup, l'assignation bash a=(un deux quatre) va retourner:
a[0] => un
a[1] => deux
a[2] => quatre


De plus, les champs contenant un espace seront explosés. Comme dans par exemple:
un:deux::quatre:et la fin

Solution en bash (assez tirée par les cheveux je l'avoue)
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#! /bin/bash
string='un:deux::quatre:et la fin'
 
until [ "$tolken" =  "$string" ]
do
        tolken=${string%%:*}    # prend le premier token
        a[$i]=$tolken           # l'affecte à l'élément du tableau
        string=${string#*:}     # supprime ce token de la chaine
        ((i++))
done
 
# affichage du tableau
for index in ${!a[@]}
do
        echo  a[$index] '=>' ${a[$index]}
done
Beaucoup plus facile en ksh:

Code :
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/ksh
string='un:deux::quatre:et la fin'
IFS=:
set -A a $string
 
# affichage du tableau
for index in ${!a[@]}
do
        echo  a[$index] '=>' ${a[$index]}
done
Edit: En bash, il y a plus simple que mon truc plus haut. Tout simplement en utilisant une affectation de tableau classique. Mais attention, il faut utiliser une substitution de variable car, assez bizarrement:
Code :
1
2
3
4
5
6
7
8
9
10
11
# espace comme séparateur (marche correctement)
a=(un deux trois) 
 
# autre séparateur (ne marche pas)
IFS=:
a=(un:deux:trois)
 
# autre séparateur avec substitution (bonne méthode)
string='un:deux:trois'
IFS=:
a=($string)
__________________
:q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
:quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
Jabber: ripat at im.apinc.org
ripat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/04/2007, 21h36   #10
Membre habitué
 
Étudiant
Inscription : janvier 2006
Messages : 501
Détails du profil
Informations personnelles :
Âge : 25

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2006
Messages : 501
Points : 113
Points : 113
Re

J'ai un petit probleme en fait encore..

Je sais qu'avec sed je peux changer quelque chose dans un fichier, mais le probleme c'est que j'aimerais changer cette occurence que sur une ligne, et donc si je fais un sed sur tout le fichier, il changera partout ce que je veux changer... alors que je veux pas changer dans tout le fichier...

vous voyez ce que je veux dire ?
italiasky est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/04/2007, 22h51   #11
Membre émérite
 
Inscription : mai 2004
Messages : 709
Détails du profil
Informations personnelles :
Localisation : Belgique

Informations forums :
Inscription : mai 2004
Messages : 709
Points : 852
Points : 852
Tu peux filtrer la substitution de sed avec un masque:

Code :
# sed '/masque/ s/a remplacer/par ceci/g'
__________________
:q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
:quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
Jabber: ripat at im.apinc.org
ripat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/04/2007, 23h07   #12
Membre expérimenté
 
Avatar de BlaireauOne
 
Inscription : mars 2007
Messages : 469
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2007
Messages : 469
Points : 576
Points : 576
Citation:
Envoyé par ripat
Tu peux filtrer la substitution de sed avec un masque:

Code :
# sed '/masque/ s/a remplacer/par ceci/g'

Fichier de données tst.txt :

info1;info2;TEXT3;info4
bla1;bla2;TEXT3;bla4

Sélection sur le n° de la ligne ou sur un "motif" :

$ sed "2s/TEXT3/AUTRE/" tst.txt
info1;info2;TEXT3;info4
bla1;bla2;AUTRE;bla4

$ sed "/bla1/s/TEXT3/AUTRE/" tst.txt
info1;info2;TEXT3;info4
bla1;bla2;AUTRE;bla4

http://pwet.fr/man/linux/commandes/sed
BlaireauOne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/04/2007, 19h19   #13
Membre habitué
 
Étudiant
Inscription : janvier 2006
Messages : 501
Détails du profil
Informations personnelles :
Âge : 25

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2006
Messages : 501
Points : 113
Points : 113
ok merci
italiasky est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h27.


 
 
 
 
Partenaires

Hébergement Web