Pb script middleline
Résolu
kamax
-
jipicy Messages postés 40842 Date d'inscription Statut Modérateur Dernière intervention -
jipicy Messages postés 40842 Date d'inscription Statut Modérateur Dernière intervention -
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.
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:
- Pb script middleline
- Script vidéo youtube - Guide
- Mas script - Accueil - Windows
- Ghost script - Télécharger - Polices de caractères
- Script cmd - Guide
- Script download - Télécharger - Édition & Programmation
16 réponses
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 !
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 !
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
Pourrais-tu être plus explicite? merci Chacual
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...
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...
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.
[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.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Salut,
Une façon de faire :
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]$;-))
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
$ 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 $;-))
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?
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 ;-((
Là par contre ça va pas être coton à gérer ;-((
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??
Non, on parle des champs contenus dans le résultat de la commande "wc -l" qui te renvoie :
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.
10 fich.txtautrement 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.
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.
[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.
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).
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
#!/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
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;-))
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.
#! /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";-))