Script shell bash sur un texte

Fermé
niceLP - 14 mai 2007 à 16:34
hugnix Messages postés 119 Date d'inscription samedi 9 juin 2007 Statut Membre Dernière intervention 27 avril 2009 - 12 févr. 2008 à 23:25
j'ai un exo qui consiste à insérer une ligne en premier argument($1)
cette ligne doit se situer au milieu d'un texte déjà constitué d'un fichier existant , par exemple :

ligne 1
ligne2
nouvelle ligne
ligne 3
ligne4

on doit le faire sans utiliser les commandes sed et awk , en calculant les lignes ; j'ai fait comme ceci mais ça plante

lignes= wc -l $2 | cut -c1

milieu= $(($lignes/ 2))

si vous avez des idées , merci
A voir également:

54 réponses

lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
12 févr. 2008 à 15:17
Salut,

pourquoi pas
root@debian:~# cat ccm.sh
#!/bin/bash
a=$(ls -l $1 | cut -d' ' -f1)
b=${a//[rwx]/"\toui\t"}
aa=${b//-/"\tnon\t"}
user=$(ls -l $1 | cut -d ' ' -f3)
groupe=$(ls -l $1 | cut -d ' ' -f4)
u=${aa:7:21} g=${aa:21:21} o=${aa:42:21}
echo -e "    \t\t\tread\t\twrite\t\texecute"
echo -e "user $user\t$u\ngroupe $groupe\t$g\nautres\t\t$o"

root@debian:~# sh ccm.sh ccm.sh
                        read            write           execute
user root               oui             oui             non
groupe lami20j          non             oui             non
autres                  non             oui             non
root@debian:~#
2
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
14 mai 2007 à 17:54
Salut,
[jp@MDK tmpfs]$ cat niceLP.sh
#! /bin/bash

echo "$1" > tmp
milieu=$(expr $(wc -l $2 | cut -d" " -f1) / 2)
split -l "$milieu" bar.txt tmp
cat tmpaa tmp tmpab > fichier
rm -f tmp*

[jp@MDK tmpfs]$ sh niceLP.sh "Ligne introduite" bar.txt

[jp@MDK tmpfs]$ cat fichier
Ligne 1
Ligne 2
Ligne 3
Ligne 4
Ligne 5
Ligne 6
Ligne introduite
Ligne 7
Ligne 8
Ligne 9
Ligne 10
Ligne 11
Ligne 12
[jp@MDK tmpfs]$ 
Voir le "man split".

;-))

Édit : La soluce à "lami20j" (enfin dans l'esprit je pense) :
#! /bin/bash

milieu=$(expr $(wc -l $2 | cut -d" " -f1) / 2)
head -"$milieu" "$2" > fichier
echo "$1" >> fichier
tail -"$milieu" "$2" >> fichier
1
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
14 mai 2007 à 19:38
Salut,

Édit : La soluce à "lami20j" (enfin dans l'esprit je pense) :
je confirme :-))
Merci.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
14 mai 2007 à 16:38
Salut,

tu as le droit d'utiliser head ou tail?
0
oui on peut le faire avec les commandes tail et head , j'ai essayé mais ça ne marche pas , à chaque fois il me supprime les lignes du fichier ( fichier)
pourtant j'ai bien mis les ">>" ; y a t il un pb avec le $milieu ?
merci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
15 mai 2007 à 12:01
Copie/Colle ton script, ton fichier de référence et ton fichier de sortie. Merci.
0
voici le script
ligneinsere

#! /bin/bash

centre=$(expr $(wc -l $2 | cut -d" " -f1) / 2)
head -"$centre" "$2" > fichier
echo "$1" >> fichier
tail -"$centre" "$2" >> fichier

execution :
$ sh ligneinsere "ligne au milieu" fichier

resultat
ligne au milieu
ligne au milieu
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
15 mai 2007 à 12:27
Juste un truc : j'ai l'impression que tu lances ton script sur le fichier même faisant office de fichier de sortie, non ?

Il faut que le fichier où tu vas lire les lignes soit différent du fichier où tu vas écrire la sortie !!!

Peut être ne suis-je pas dans l'exactitude de la chose, dans ce cas là, sorry ;-(
0
ok tu as raison , désolé je prenais le meme fichier d'entrée et de sortie
merci encore
0
bonjour a tous j'ai le même problème mais je l'ai résolu autrement bon c'est sur c'est quand même plus facile...


head -3 fichier > temp

echo ligne de texte >> temp

tail -3 fichier >> temp

cat temp > fichier

rm temp

cat fichier

j'ai essayé d'analyser la soluce au dessus mais je bloque avec les variables j'ai pas tout compris, wc -l ok, mais aprés..........................

A+
0
quand le nombre de ligne est pair, ca fonctionne par contre quand c'est impair, il efface une ligne.

pour faire un test en plus, je dois utiliser quoi ?
0
hugnix Messages postés 119 Date d'inscription samedi 9 juin 2007 Statut Membre Dernière intervention 27 avril 2009
20 janv. 2008 à 19:43
Salut,
à mon avis, vu que la nombre de ligne est impair, il le coupe bien en deux mais en deux partie inégale 91/2=45,5 ce qui donne 46/45, tu me suis?
Je t'ai trouvé ça, je pense que ça devrait te satisfaire, du moins je l'espère, sinon je peux te pondre un petit script qui peux te permettre de donné la valeur a head et a tail, bon c'est sur si ton fichier 351443134143142346 lignes, prévoit une calculette....

#! /bin/bash

centre1=$(expr $(wc -l $2 | cut -d" " -f1) / 2)
centre2=$(($centre1 +1))
head -"$centre" "$2" > fichier
echo "$1" >> fichier
tail -"$centre2" "$2" >> fichier




Dsl pour le double post jipicy, j'ai voulu l'éditer mais tu m'as devancés de quelque secondes..............

Merci pour eux ;)
0
Bonjour,

J'ai le même problème aussi. ta solution est intéressante, mais tu changes le nom du fichier; dans mon exo, on ne doit pas le changer !

Alors je dois encore chercher la solution. je vais voir comment je peux changer ton script.

Mais, bien sûr, si tu peux donner un coup de main, ça peut toujours accélérer les choses!

Merci
0
bonjour,

Ce que je voudrais, c'est avec un fichier yo :

eeeee
eeeee
eeeee
eeeee



Insérer au milieu : hello, en sautant une ligne ; cela devrait donner :

eeeee
eeeee
hello
eeeee
eeeee


Or, en essayant les scripts proposés, je n'arrive pas à ce résultat, soit

-dans le script avec, head et tail , des lignes sont ajoutées ; ainsi j'obtiens : cat yo :

eeeee
eeeee
eeeee
eeeee
hello
eeeee
eeeee
eeeee

Autrement dit, il me rajoute des lignes de texte, copies de lignes du texte, au texte

Ou alors, rien ne change dans les deux fichiers : fichier et yo

cat fichier :

eeeee
eeeee
eeeee
eeeee

cat yo

eeeee
eeeee
eeeee
eeeee


Je ne suis pas sorti de l'auberge !

Merci tout de même


ps : scripts de ref.:
---------------------------

#! /bin/bash

centre1=$(expr $(wc -l $2 | cut -d" " -f1) / 2)
centre2=$(($centre1 +1))
head -"$centre" "$2" > fichier
echo "$1" >> fichier
tail -"$centre2" "$2" >> fichier

rem.: centre, n'est pas une variable. Or vous lui demandez une valeur!
fichier, sort yo, et l'insertion 'hello' mais avec des copies de lignes en plus. ce qui fait que l'insertion n'apparait pas au milieu.
------------------------------------

! /bin/bash

echo "$1" > tmp
milieu=$(expr $(wc -l $2 | cut -d" " -f1) / 2)
split -l "$milieu" bar.txt tmp
cat tmpaa tmp tmpab > fichier
rm -f tmp*

rem.: fichier tmpaa,, tmpab, n'existent pas
bar changé par mon fichier
0
makoko Messages postés 53 Date d'inscription mercredi 6 février 2008 Statut Membre Dernière intervention 25 novembre 2012
6 févr. 2008 à 08:30
bonjour,


J'obtiens bien ce que je voudrais avec ce script (logique): sh mo hello yo , mais pas où, il fallait.

#! /bin/bash

milieu=$(expr $(wc -l $2 | cut -d" " -f1) / 2)
head -"$milieu" "$2" > fichier
echo "$1" >> fichier
tail -"$milieu" "$2" >> fichier

cat yo

eeeee
eeeee
eeeee
eeeee


donc, échec, toujours ....

mais sur fichier : cat fichier :

eeeee
eeeee
hello
eeeee
eeeee

je voudrais ce résultat aussi dans yo!

Je ne suis pas au bout du roulot ....

merci
0
makoko Messages postés 53 Date d'inscription mercredi 6 février 2008 Statut Membre Dernière intervention 25 novembre 2012
6 févr. 2008 à 09:06
Je l'ai eu !

En partant du script de jipicy (le 2e), que je remercie au passage, plus simple et plus judicieux (le premier, j'ai eu du mal ,avec split!), j'ai demandé à la fin, tout simplement de 'mv fichier yo', et le tour (le tout aussi) était joué!

j'avais enfin, non de dieu ! ce que je voulais :

eeeee
eeeee
hello
eeeee
eeeee


j'aurais du venir sur votre site plus tôt : seul, on a toujours plus de mal, malgré le cours et du matériel qu'on peut trouver ailleurs. Mais c'est dans l'échange "vive et animé", ou en collectif, qu'on avance, en testant les solutions, en les remaniant, en tentant de comprendre leur logique.

j'ai passé la nuit entière là-dessus, mais cette fois, ça y est, j'ai enfin réussi. cela faisait des jours, que j'étais là-dessus, mais tout seul, pas facile, même si on avance un peu, mais pas autant que quand on est épaulé !

Merci à vous, Merci aux contributeurs
0
makoko Messages postés 53 Date d'inscription mercredi 6 février 2008 Statut Membre Dernière intervention 25 novembre 2012
6 févr. 2008 à 16:28
bonjour,

je reviens vers vous, avec un problème, simple, mais je galère un peu ! je débute sérieusement sur unix.

pb : je fais une redirection de 'env' sous unix, donc, je vais avoir : pwd, user, mail, logname, home.

ex. : env > toi

je souhaite sortir (extraire) et afficher, numéro de ligne, ), nom de l'occurence, = , chaque occurrence de user (l'utilisateur qui exécute le script) , de cette façon:

1) pwd=
2) user=
jusqu'à
4) home=

et pouvoir aussi le faire autant de fois, que ces occurrences là, sont contenues dans le fichier : dans le cas, par ex., où je redirige plusieurs fois, env, dans le même fichier, toi.

travail déjà effectué : j'ai essayé par ex. : find / -pwd 'toi' ( pour faire un premier test: décomposer tout pb, en pbs, plus simples), mais, j'ai eu le message d'erreur suivant :
find: invalid predicate `-pwd'

je continue la recherche.

Merci pour votre aide d'avance
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
6 févr. 2008 à 16:49
Salut,

Un truc dans ce genre :
$ env | egrep "^(HOME|USER|PWD|SHELL)" | cat -n
     1  SHELL=/bin/bash
     2  USER=jp
     3  PWD=/home/jp/tmpfs
     4  HOME=/home/jp
;-))
0
makoko Messages postés 53 Date d'inscription mercredi 6 février 2008 Statut Membre Dernière intervention 25 novembre 2012
6 févr. 2008 à 17:59
Bonjour,

J'ai avancé. C'est grep, qu'il faut utiliser.
J'ai redirigé 3 fois, ma sortie (env > toi (*3))

Ainsi, j'obtiens :

PWD=
PWD=
PWD=


Ce que je veux, c'est :

1) PWD=
2) PWD=
3) PWD=

Et ceci pour les autres occurrences aussi, bien sûr : tout cela redirigé vers un fichier, dans un script.

La recherche continue.

Merci de votre contribution
0
hugnix Messages postés 119 Date d'inscription samedi 9 juin 2007 Statut Membre Dernière intervention 27 avril 2009
6 févr. 2008 à 18:02
Effectivement j'ai oublié de mettre une ligne... ormalement avec ça a la fin ton fichier garderas le même nom
cat temp > $2 | rm temp 
, par contre moi il le met bien au millieu, je viens de réessayer sur un fichier de onze ligne et ca donné ca

11111111111111111
11111111111111111
11111111111111111
11111111111111111
11111111111111111
00000000000000000
11111111111111111
11111111111111111
11111111111111111
11111111111111111
11111111111111111
11111111111111111

Maintenant si tu essaye avec un des scripts au dessus ça devrait donner ça, normalement.

1111111111111
0000000000000
2222222222222
1111111111111


Je précise que le script que j'ai posté ne fonctionne que pour un nombres de lignes impair, avec un nombre de ligne pair, les scripts proposé au dessus fonctionne très bien, le problème c'est que a chaque fois il faut connaitre le nombre de lignes, ce qui serait intéressant c'est d'essayer de faire un fichier qui insère une ligne au milieu sans tenir compte du fait que le nombre de lignes soit pair ou impair.


"j'aurais du venir sur votre site plus tôt : seul, on a toujours plus de mal, malgré le cours et du matériel qu'on peut trouver ailleurs"
Oui les gens ici sont toujours prés à t'aider si de ton coté te fait un p'tit quelquechose, donc ceux qui attendent d'avoir une réponse toute cuite se gourre un peu, et c'est bien, c'est comme ça que l'on apprend, et si t'as des problémes pour tes scripts jipicy seras là :)))))) il m'as pas mal aidé pour mon script du jeu du pendu , si tu veux y jeter un coup d'oeil http://www.commentcamarche.net/forum/affich 3900064 script bash avance#0 regarde a la fin j'ai posté une version final, mais j y ai retrouvé quelque petites erreurs mais en gros ça marche comme il faut.


Pour ton autre exercices le résultat final ce serait pas un truc du genre?

1) PWD=/home/toi
2) USER=toi
3) MAIL=/var/spool/mail/toi
4) LOGNAME=toi
5) HOME=/home/toi
...

Parce que j'ai du faire un exercice dans le même genre, j'avais la commande env redirigé 5 fois dans le fichier XX et je devais y rajouter le numero de la ligne plus une paranthése, donc si t'as besoin.... mais je pense que la soluce de jipicy devrait te satisfaire!?
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
6 févr. 2008 à 18:40
Tiens, j'ai mieux encore :
$ env | egrep "^(HOME|USER|PWD|SHELL)" | nl -w 1 -s ") "
1) SHELL=/bin/bash
2) USER=jp
3) PWD=/home/jp/tmpfs
4) HOME=/home/jp
;-))
0