IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Récupérer l'emplacement d'un texte dans un fichier


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Récupérer l'emplacement d'un texte dans un fichier
    Bonjour,

    Exemple d'un fichier (la longueur des lignes ainsi que celle du fichier est variable):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    xxxtotoxxx
    xxxtotoxxxxx
    xxxxxxxxtotoxxxx
    xxxxxxx
    J'aimerais savoir s'il y a un moyen de savoir ou se trouve le dernier "toto" afin de séparer le fichier (sans doute avec un tail)
    Si cela pouvait être possible de gérer le texte à trouver en hexadécimal ce serais le top.

    Donc avoir au final ces 2 fichiers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    xxxtotoxxx
    xxxtotoxxxxx
    xxxxxxxx
    S'il est plus facile de séparer le fichier sur chaque "toto" c'est encore mieux.

    J'avais pensé à la fonction awk qui doit pouvoir le faire mais je ne la maitrise pas du tout.

    Merci d'avance.

  2. #2
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    $ cat > toto # generer le fichier de test
    xxxtotoxxx
    xxxtotoxxxxx
    xxxxxxxxtotoxxxx
    ^D
     
    $ count=0
    $ while read 
    > do
    > # pour chaque ligne lue
    > echo $REPLY | grep -i toto > fichier.$count # copier la ligne dans fichier.0 fichier.1 etc...
    > count=$(( $count + 1 ))
    > done < toto  # lecture du fichier toto
    $ cat fichier.0  # juste pour vérifier le resultat
    xxxtotoxxx
    $ cat fichier.1 # juste pour vérifier le resultat
    xxxtotoxxxxx
    $ cat fichier.2 # juste pour vérifier le resultat
    xxxxxxxxtotoxxxx
    $ unset count
    $ rm fichier.[0-3] toto # epurer la demonstration
    notes que les lignes ne contenant pas la chaine à rechercher donne un fichier.numero_de_ligne vide ce qui permet de savoir quelles lignes du fichier a analyser ne sont pas représentatives de la chaine à rechercher sans réouvrir le fichier à analyser. C'est pourquoi il est utile de faire cette méthode pour croiser les deux résultats/cas.

    enfin le comptage commence par 0 mais tu veux démarrer à 1 il suffit de faire
    à la place de "=0"

  3. #3
    Membre émérite Avatar de jmelyn
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2007
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Oui oui, il y a bien la commande awk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    lastLine=$(awk '/toto/ {l=NR} END {print l}' file)
    head -n $(($lastLine-1)) file > file1
    tail -n $lastLine file > file2
    mais on peut faire sans aussi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    lastLine=$(grep toto -n file | tail -1 | cut -d ':' -f 1)
    head -n $(($lastLine-1)) file > file1
    tail -n $lastLine file > file2
    C'est clair ou faut une explication?

  4. #4
    Invité
    Invité(e)
    Par défaut
    @frp31: merci mais ta version ne donne pas ce que je souhaite au final puisque que ça ne coupe pas les fichier sur toto. Ca permet juste d'avoir les lignes contenant toto.

    @jmelyn
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    lastLine=$(awk '/toto/ {l=NR} END {print l}' file)
    head -n $(($lastLine-1)) file > file1
    tail -n $lastLine file > file2
    Ca me donne ces 2 fichiers.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    xxxtotoxxx
    xxxtotoxxxxx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    xxxtotoxxxxx
    xxxxxxxxtotoxxxx
    xxxxxxx
    Comme ceci c'est un peu mieux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    lastLine=$(awk '/toto/ {l=NR} END {print l}' file)
    head -n $lastLine file > file1
    tail -n +$lastLine file > file2
    Ca me donne ça dans le 2ème fichier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    xxxxxxxxtotoxxxx
    xxxxxxx
    Par contre je connais très peu awk donc j'ai du mal à cerner ce qu'il fait.
    Chaque fois qu'il trouve une ligne avec toto il stocke le numéro de la ligne lue (NR) dans l. Quand il a terminé d'analyser le fichier il retourne l qui est donc stocké dans lastLine. C'est bien ça ?

    Le 2ème script ne donne pas non plus ce que je souhaite. J'aimerais obtenir ceci (comme indiqué dans mon 1er poste) :
    Je peux toujours faire ceci, mais peut être qu'il y a mieux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -i s/.*toto/toto/ file2

  5. #5
    Membre émérite Avatar de jmelyn
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2007
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    L'énoncé n'était pas clair sur le sujet. Alors oui, il manquait le "+" dans le tail, et ton interprétation de awk est juste. Maintenant, pour faire exactement ce que tu demandes, c'est un peu plus compliqué:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    pattern="toto"
    read -d "\n" line beg end < <(awk -v p="$pattern" '
      $0 ~ p \
      {
        line=NR
        i=index($0, p)
        beg=substr($0, 1, i-1)
        end=substr($0, i)
      }
      END {print line "\n" beg "\n" end}' file)
    head -n $(($line-1)) file > file1
    echo "$beg" >> file1
    echo "$end" > file2
    tail -n +$(($line+1)) file >> file2
    La commande awk renvoie trois lignes qui sont assignées à trois variables grâce à read:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ligne 1: le numéro de ligne du dernier "toto" dans le fichier
    ligne 2: le début de la fameuse ligne (jusqu'à "toto")
    ligne 3: la fin de cette ligne (commençant à "toto")
    Ensuite, je rajoute ces portions de lignes aux deux fichiers de destination.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par jmelyn Voir le message
    L'énoncé n'était pas clair sur le sujet
    Désolé, c'est pour ça que j'avais mis un exemple de ce que je voulais obtenir.

    Merci pour ton dernier script, je vais regarder ça tranquillement pour bien comprendre comment il marche. En tout cas, il fait bien ce que je veux.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Finalement j'ai toujours un problème
    S'il y a un caractère "nul" (00 en hexadécimal) le résultat est coupé et ce qu'il y avait après n'apparait pas en sortie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    xxxtotoxxx
    xxxxxxxxxxx
    xxxxxxxxtotoxx(nul)x
    xxxxxxxx
    Donnera:
    Par contre j'ai trouvé quelque chose qui va simplifier mon problème.
    J'ai trouvé une chaîne de caractère unique qui correspond presque à l'endroit de séparation que je veux.

    Exemple du fichier en hexadécimal ci-dessous (le fichier réel est beaucoup plus gros, il fait 36Mo). Il y a souvent des 00 et il peut y avoir des 0a (retour chariot) utilisés dans le numéro des éléments du fichier. Cet exemple est donc bien représentatif du fichier final.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    0a 74 00 68 00 61 00 74 00 20 00 64 00 61 00 79 00 2e 00 00 00 01 00 00 00 11 00 00 80 52 00 65 00 74 00 75 00 72 00 6e 00 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    La partie indiquant la séparation est en hexadécimal "80 52 00 65 00 74 00 75 00 72 00 6e 00 2e". J'aimerais donc séparer ce fichier en 2 partie:
    - la 1ère irait jusqu'à "80 52 00 65 00 74 00 75 00 72 00 6e 00 2e"
    - la 2ème commencerait après cette partie.

    Est-il possible de savoir que cette chaîne de caractère commence en position 28 (dans cet exemple) afin d'utiliser head et tail pour séparer le fichier ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. récupérer une partie d'un texte dans une variable
    Par Bubale dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 14/05/2008, 11h18
  2. Réponses: 1
    Dernier message: 29/09/2007, 09h46
  3. Réponses: 9
    Dernier message: 19/09/2007, 16h16
  4. Réponses: 12
    Dernier message: 21/02/2007, 09h44
  5. [MySQL] Récupérer la taille d'un texte dans la BDD
    Par Death83 dans le forum PHP & Base de données
    Réponses: 14
    Dernier message: 02/08/2006, 21h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo