Pb script middleline

Résolu
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.
Configuration: Windows XP
Firefox 2.0.0.6

16 réponses

  1. 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
    1. 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
      1. 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
        1. Modérateur
          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
      2. 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
        1. Modérateur
          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
          1. 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
            1. 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
          2. Modérateur
            $ 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
            1. 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
              1. Modérateur
                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
                1. 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
                  1. Modérateur
                    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
                2. 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
                  1. Modérateur
                    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
                    1. 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
                      1. Modérateur
                        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
                        1. 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
                          1. Modérateur
                            #! /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