Pb script middleline

Résolu/Fermé
kamax - 31 août 2007 à 14:40
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 - 31 août 2007 à 19:08
bonjour je souhaite faire un script sous unix qui m'insère une phrase au milieu d'un texte d'un autre fichier, tout en conservant le nom du fichier texte. Je ne dois ni utiliser sed ni awk.
J'ai pensé travailler avec des fichiers temporaires, l'un pour stocker la première partie du texte, l'autre pour la deuxième partie
Ensuite je veux insérer ma phrase saisie en arg1 dans le premier fichier temp.
Puis pour finir recoller les deux fichier temp pour me redonner le fichier texte complet donné en arg2, avec la ligne insérer au milieu.

voici mon script:

#!/bin/bash
#script pour inserer une ligne au milieu d'un texte

#recuperation des arguments dans des variables
arg1=$1 #la phrase saisie
arg2=$2 #le fichier texte
x=$(wc-l $2) # le nombre de ligne dans le fichier <= j'ai une erreur ici
middle= $(($x/2)) <= j'ai aussi une erreur ici
debut=$x-$middle #nombre de lignes dans la premiere partie du texte
fin=$x-$debut #nombre de lignes dans la seconde partie du texte


#Copie, s'il existe, du contenu du fichier passe en argument dans 2 fichiers
#temp1 et temp2
cat $( head -$debut $arg2 ) > temp1.txt
cat $( tail -$fin $arg2) > temp2.txt

# Affichage de l'argument 1 tout en redirigeant la sortie standard vers le
#fichier temp de debut
echo $arg1 >> temp1.txt

# Ajout a la fin du fichier temp de debut le fichier temp de fin
cat temp2.txt >> temp1.txt
cat temp1.txt > $arg2
rm temp1.txt temp2.txt
cat $arg1

Pouvez-vous me dire ce qu'il ne va pas dans mon script, ou pouvez-vous me proposer une solution sur une autre démarche à suivre.
Merci.
A voir également:

16 réponses

Chacual Messages postés 230 Date d'inscription jeudi 28 juin 2007 Statut Membre Dernière intervention 15 octobre 2007 150
31 août 2007 à 14:45
Erreur 1 :
Quand tu veux renseigner une variable avec le résultat d'une commande, tu dois mettre ta commande entre quotes `` (Alt Gr + 7) et non pas entre accolades.

Erreur 2 :
$x/2 ne fonctionne pas !!
Si tu veux effectuer des calculs arithmétiques, tu dois utiliser la commande expr et suivre la remarque ci-dessus (``).

Dis-moi si tu ne t'en sors pas !
0
je vois pas très bien comment mettre en place ce que tu m'as dit. J'ai quand même les ereurs. Peut-être je ne les place pas au bon endroit?
Pourrais-tu être plus explicite? merci Chacual
0
Chacual Messages postés 230 Date d'inscription jeudi 28 juin 2007 Statut Membre Dernière intervention 15 octobre 2007 150
31 août 2007 à 15:01
x=$(wc-l $2)
devient
x=`wc-l $2`

Pour expr, je ne me souviens plus exactement de la syntaxe mais c'est quelque-chose comme :
middle= $(($x/2))
devient
middle=`expr $x / 2`

Et attention à ne pas laisser d'espaces autour du = quand tu affectes des variables. Le Shell UNIX est sensible à la casse mais aussi aux espaces...
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
31 août 2007 à 15:18
Salut,

x=$(wc-l $2) est tout simplement la forme moderne de x=`wc-l $2`, beaucoup plus lisible et recommandée.

Il en est de même pour $(($x/2)) qui doit supplanter `expr $x / 2` (qui peut aussi s'écrire "$(expr $x / 2)").

;-))
0
après les modifications que tu m'as suggérés, voilà ce que me dit le prompt:

[belkacem.berbache@unix chapter7]$ sh middleline "salut tous" monText
middleline: line 7: wc-l: command not found
expr: syntax error
cat: salut: No such file or directory
cat: tous: No such file or directory
tail: unrecognized option `---'
Try `tail --help' for more information.
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
31 août 2007 à 15:34
Salut,

Une façon de faire :
[tmpfs]$ cat fich.txt

ligne 1
ligne 2
ligne 3
ligne 4
ligne 5
ligne 6
ligne 7
ligne 8
ligne 9
ligne 10

[tmpfs]$ cat foo.sh

#! /bin/bash

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

[tmpfs]$ ./foo.sh "ligne insérée" fich.txt

[tmpfs]$ cat fich.txt

ligne 1
ligne 2
ligne 3
ligne 4
ligne 5
ligne insérée
ligne 6
ligne 7
ligne 8
ligne 9
ligne 10

[tmpfs]$
;-))
0
cette solution me convient. Seulement peux-tu m'expliquer ce que (wc -l $2 | cut -d " " -f1) produit? enfin après le pipe car je ne connais pas la commande cut -d. Merci jipicy
0
Chacual Messages postés 230 Date d'inscription jeudi 28 juin 2007 Statut Membre Dernière intervention 15 octobre 2007 150
31 août 2007 à 15:53
cut sert à découper une chaine.
L'option -d te permet de définir le délimiteur (Ici " " soit espace).
L'option -f te permet de choisir le "field" à extraire.
Donc dans ce cas, on découpe le premier champ avant l'espace
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
31 août 2007 à 16:03
$ wc -l fich.txt   # ta commande à toi
  
10 fich.txt   # qui affiche le nbr de ligne et le nom du fichier

$ wc -l fich.txt | cut -d " " -f1   # la commande "cut" coupe en fonction 
                                               # du délimiteur (d " ") 
                                               # et affiche le champ spécifié (-f1)

10   # on affiche bien le 1er champ

$ wc -l fich.txt | cut -d " " -f2   # là on demande d'afficher le second champ (-f2)

fich.txt   # le résultat est bien le fichier

$
;-))
0
ton script fonctionne très bien. juste un soucis, c'est qu'en relancçant le script, il m'écrase la ligne inséréé précédement pour m'insérer la nouvelle ligne saisie en paramètre. C'est gênant car je ne peux pas rajouter de ligne de ce fait à mon texte. Ne serait-il pas mieux d'utiliser des fichier temp pour éviter ce pb? et comment le faire à partir de ton script?
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
31 août 2007 à 16:33
Le problème vient du fait qu'on est parti sur un nombre de ligne "pair" et que maintenant avec la ligne rajoutée le nombre de ligne du fichier est "impair", de ce fait la division est arrondie au chiffre inférieur ce qui scinde le fichier au même endroit.

Là par contre ça va pas être coton à gérer ;-((
0
Pourrais-tu m'expliquer -f1 et -f2, je ne comprends pas. Ce sont des champ, mais quels champs? est-ce que tu veux parler des arguments $1 et $2??
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
31 août 2007 à 17:03
Non, on parle des champs contenus dans le résultat de la commande "wc -l" qui te renvoie :
10 fich.txt
autrement dit, si on considère (et on le considère vu qu'on l'a défini par '-d " "') l'espace entre le nombre 10 et le nom du fichier fich.txt comme caractère séparateur, il y a effectivement 2 champs (un de chaque côté de l'espace), affichables par la commande par -f1 ou -f2.

Dans une phrase où le caractère séparateur est l'espace, chaque mot de cette phrase correspond à 1 champ et peut être mis en correspondance par la valeur de son champ.
0
après les modifications que tu m'as suggérés, voilà ce que me dit le prompt:

[belkacem.berbache@unix chapter7]$ sh middleline "salut tous" monText
middleline: line 7: wc-l: command not found
expr: syntax error
cat: salut: No such file or directory
cat: tous: No such file or directory
tail: unrecognized option `---'
Try `tail --help' for more information.
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
31 août 2007 à 17:35
Tu peux afficher ton code dans son intégralité s'il te plait, merci. (colle-le avec le bouton de mise en forme qu'on voit bien si la syntaxe et tous les espaces sont bien respectés).
0
voici mon script actuellement. Le problème que je recontre maintenant c'est que je ne parviens pas à concaténer les 2 fichiers temp, et surtout mon fichier texte se vide alors qu'il contenait quelque chose.

#!/bin/bash
#script pour inserer une ligne au milieu d'un texte

#recuperation des arguments dans des variables
arg=$1 #la phrase saisie
arg2=$2 #le fichier texte

#middle of monText.txt
middle=$(expr $(wc -l $2 | cut -d " " -f1) / 2)

#begin=number of lines in the first part of monTexte, then insert it in temp1
debut=$(head -"$middle" "$arg2")
echo $debut > temp1
echo $arg1 >> temp1 #here insert the arg1 at the end of temp1

#end=number of lines in the second part of monTexte, then insert it in temp2
fin=$(tail -"$middle" "$arg2")
echo $fin > temp2

echo $temp1 > $arg2 #replace content of arg2 by temp1
echo $temp2 >> $arg2 #insert temp2 at the end of arg2

rm temp1 temp2
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
31 août 2007 à 18:05
Modifie ton script comme ci-dessous. En gras les lignes modifiées en italique les anciennes....
#!/bin/bash
#script pour inserer une ligne au milieu d'un texte

#recuperation des arguments dans des variables
#+ arg=$1 #la phrase saisie
arg1=$1 #la phrase saisie
arg2=$2 #le fichier texte

#middle of monText.txt
middle=$(expr $(wc -l $2 | cut -d " " -f1) / 2)

#begin=number of lines in the first part of monTexte, then insert it in temp1
debut=$(head -"$middle" "$arg2")
#+ echo $debut > temp1
echo "$debut" > temp1
#+ echo $arg1 >> temp1 
echo "$arg1" >> temp1 #here insert the arg1 at the end of temp1

#end=number of lines in the second part of monTexte, then insert it in temp2
fin=$(tail -"$middle" "$arg2")
#+ echo $fin > temp2
echo "$fin" > temp2

#+ echo $temp1 > $arg2
cat temp1 > "$arg2" #replace content of arg2 by temp1
#+ echo $temp2 >> $arg2
cat temp2 >> "$arg2" #insert temp2 at the end of arg2

rm temp1 temp2
;-))
0
c'est ok cette fois, excepté que je ne parviens pas à gérer un nombre de lignes impair. C'est à dire que ça marche que pour un nombre de lignes pair, sinon, la ligne insérée écrase la ligne actuelle du milieu du texte.
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
31 août 2007 à 19:08
#! /bin/bash

ligne=$(expr $(wc -l $2 | cut -d " " -f1))

case "$ligne" in
*[02468])       middle=$(expr $(wc -l $2 | cut -d " " -f1) / 2)
                debut=$(head -"$middle" "$2")
                fin=$(tail -"$middle" "$2")
                ;;
*[13579])       middle=$(expr $(wc -l $2 | cut -d " " -f1) / 2)
                middles=$(expr $middle + 1)
                debut=$(head -"$middles" "$2")
                fin=$(tail -"$middle" "$2")
                ;;
*)              echo "Error"
                exit
                ;;
esac

echo "$debut" > $2
echo "$1" >> "$2"
echo "$fin" >> "$2"
cat "$2"
;-))
0