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 :

[bash] Extraire des lignes d'une catégorie souhaitée (sans awk)


Sujet :

Shell et commandes GNU

  1. #21
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Et puis je vois que tu t'accroches donc j'ai décidé de te donner un coup de pouce
    Un grand merci pour cette précieuse proposition car elle m’offre un nouveau point de vue car je n’avais pas encore vu de ‘<<<’ en bash par exemple jusqu’à aujourd’hui 😊
    Pourrais-tu s’il te plait m’expliquer (commenter en français) ces 2 lignes ?
    [CODE]
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    		firstLig="$firstLig, $nom ($prenom) [$titre]"
    	done <<< $(grep ":$1$" "$2")


    Me concernant, j’ai continué à travailler sur le script et voilà ce que j’ai obtenu (même si ça n’a pas fonctionné…) :
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    #! /bin/bash
    echo
    echo "Ce script a pour but d'établir une liste qui reprend les auteurs et les titres des livres correspondant à une catégorie donnée"
     
    #vérifie que le fichier contenant la liste des livres existe bien
    #vérifie si le chemin est fourni comme 1er arg à la cmd
    if [ -z "$1" ]
    then
    	echo "Utilisation $0 <livres.txt>"
    	echo "Aucun fichier input n'a été donné"
    	exit 1
    fi
     
    #verifie si ce meme fichier existe
    if [ ! -f "$1" ]
    then
    	echo "Le fichier $1 n existe pas"
    	exit 2
    fi
     
    #demander à l'utilisateur quelle catégorie de livres il souhaite extraire
    read -p "Quelle catégorie souhaiteriez-vous extraire ?" choixCategorie
     
    #extraire ces livres du fichier et créer un fichier avec : le titre, la liste des livres et ensuite le nombre de livres extraits
    while read choixCategorie
    do
        # Récupérer les données des différents champs
    	nom="$(echo "$choixCategorie" | cut -d";" -f1)"
    	prenom="$(echo "$choixCategorie" | cut -d";" -f2)"
    	titre="$(echo "$choixCategorie" | cut -d";" -f3)"
    	annee="$(echo "$choixCategorie" | cut -d";" -f4)"
    	categorie="$(echo "$choixCategorie" | cut -d";" -f5)"
     
    	fichier="home/user/livres.txt"
    	fichier2="home/user/fichier2.txt"
     
    	# Compter le nombre de livres
    	#Première façon de faire
    	if [[ ! -f "$fichier" ]]
    	then
    		echo "le fichier n'existe pas"
    	else
    		lig="$home/user/livres.txt/*"
    		count=0
    		for nbLigne in $(cat /home/user/fichier.txt | wc -l)
    		do
    			if [[ ! -z "$fichier" ]]
    				then count=$(($count+1))
    			fi
    		done
    		echo "Il y a $count lignes trouvées"
     
    	#à refaire car il s'agit d'un mauvais réajustement d'un code trouvé sur le net...
    	TAILLE=$(wc -l /home/user/fichier2.txt | cut -d " " -f5)
    	for i in $(seq 1 $TAILLE) ; do
    	  nbLivres=$(sed -n -e ${i}p /home/user/fic2.txt)
    	  sed -i -e "s/nbLivres${i}/$nbLivres/g" /tmp/fichier1 
    	done
     
    	#créer le fichier reprenant titre liste de livres et nombres de livres extraits
    	#Première façon de faire (pas correct)
    	while IFS=':' read nom prenom titre annee categorie
    	do
    		read choixCategorie | touch -p "/home/livres/$1"
    		"$choixCategorie" = "$1" && echo "correspondance \"$categorie\" : $nom $prenom $titre $annee"
    	done < "$fichier2"
     
    	#Deuxième façon de faire (pas correct non plus)
    	lignes=$(cut -d IFS=':' -f5 livres.txt)
    	while read choixCategorie; do
    	touch /home/user/fic2.txt
    	cat /home/user/livres.txt | cut -d: -f1,3 | grep -w "$choixCategorie" 
    	done
    	cat $lignes /home/user/livres.txt >> touch /home/user/fic{SCIENCES,BD,ROMAN}.txt
     
    	#Troisième idée comme façon de faire (pas terminée)
    	cat < $fichier > $fichier2
     
    done
    Petite précision qui pourrait apporter de la clarté : ce que j’ai essayé d’écrire dans la boucle while (#Deuxième façon de faire) correspondrait plus ou moins à ceci en SQL puisqu’il ne s’agit ici réellement d'extraire des lignes d’un tableau mais d'un fichier à plat :
    Select nom, prenom, titre from livres.txt where categorie = ‘’$1‘’
    Pour ensuite ajouter ces lignes dans le nouveau fichier2

    Remarque : ces lignes SQL ne sont pas correctes car je les ai écrites en brouillon pour m’aider visuellement car je ne suis pas parvenu non plus à écrire un algorithme pour ce script.
    Dernière modification par Invité ; 18/07/2022 à 19h34.

  2. #22
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par environnementBash Voir le message
    Pourrais-tu s’il te plait m’expliquer (commenter en français) ces 2 lignes ?
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    		firstLig="$firstLig, $nom ($prenom) [$titre]"
    	done <<< $(grep ":$1$" "$2")
    Ben la première c'est une variable à laquelle je concatène son contenu actuel plus autre chose. A chaque tour de boucle la variable s'agrandit (l'instruction var=truc ne devrait pourtant pas te poser de soucis métaphysiques...)
    Et la seconde qui termine la boucle indique que ce sera la commande qui servira à alimenter le read de la boucle.
    Ca permet de réécrire ce type de boucle (qui, j'espère, ne t'est pas inconnu)
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    commande |while read ligne; do
    	echo "$ligne"
    done
    en
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while read ligne; do
    	echo "$ligne"
    done <<< $(commande)
    Avec la première écriture, à cause du pipe, toute variable interne à la boucle est perdue en fin de boucle. Avec son équivalent <<< il n'y a pas de pipe donc je conserve après le "done" la variable créée/remplie dans la boucle.

    Citation Envoyé par environnementBash Voir le message
    cat $lignes /home/user/livres.txt >> touch /home/user/fic{SCIENCES,BD,ROMAN}.txt
    Fais un effort un peu au lieu de touiller les instructions en espérant tomber en marche. Une redirection c'est écrire le contenu de la commande dans un fichier. Là, tu vas créer un fichier nommé "touch" et ensuite ça va tenter d'exécuter la commande "/home/user/fic{SCIENCES,BD,ROMAN}.txt" (sans parler de ce "cat $lignes" signifiant "affiche le fichier dont le nom est stocké dans la variable lignes" ).

    Et puis (ça fait longtemps que je me pose la question) pourquoi tu cherches à faire du touch systématiquement dans tous tes essais ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #23
    Invité
    Invité(e)
    Par défaut
    Merci beaucoup pour toutes ces précisions et la remarque, ça me motive à continuer mon script

  4. #24
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 550
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    <<< $( commande) est une erreur. Ça ne génère pas d'erreur, mais c'est un peu comme cat "$file" | grep.
    <<< doit être utilisé avec des variables : grep 'motif' <<<"$var".

    la forme correcte est < <(commande), où on utilise une Substitution de processus dont on redirige la sortie.

    EDIT : il est maladroit, au moins, de lire deux fois le même fichier, alors qu'une seule suffirait pour effectuer toutes les opérations requises.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

Discussions similaires

  1. [XL-2010] Extraire des lignes d'une colonne situées entre 2 mots constants
    Par xico8 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 03/02/2015, 10h07
  2. Extraire des lignes avec une formule
    Par maxxxime dans le forum Excel
    Réponses: 9
    Dernier message: 15/06/2010, 17h05
  3. [XL-2007] Extraire des lignes en fonction d'une valeur de cellule dans un autre fichier
    Par MisterTambo dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 19/08/2009, 10h42
  4. Réponses: 3
    Dernier message: 21/01/2009, 13h49
  5. Extraire des lignes d'un fichier en commande bash
    Par newnew dans le forum Linux
    Réponses: 3
    Dernier message: 27/07/2004, 16h22

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