Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 11/12/2011, à 16:46

cristobal78

(résolu) Choisir un mot dans une liste numérotée par son no. de ligne

Bonjour à tous les forts en bash !

Je tente de mettre au point un script qui va me permettre de sélectionner un fichier à partir de son numéro de ligne dans une liste.
Mon idée est de commencer par :

find -iname "fichier_recherché*".

- J'ai mis le paramètre -iname pour l'insensibilité à la casse.
- J'ai mis une  "  à la fin car je ne suis pas forcément sur du nom exact du fichier.

Pour choisir le bon fichier dans la liste qui va m'apparaitre il faudrait  qu'elle soit numérotée un peu comme ça par exemple :

1 - fichier_recherché1
2 - fichier_recherché12
3 - fichier_recherché25
4 - fichier_recherché999

Maintenant je devrais pouvoir sélectionner le fichier qui m'intéresse par le No de la ligne où il apparait dans la liste ci dessus.
Par exemple si le fichier qui m'intéresse est   "fichier_recherché25" alors je voudrais le sélectionner par le No 3.

Ensuite je crée une variable avec le nom du fichier de la ligne 3 et je poursuis mon script avec cette variable..

C'est là mon pb : comment fait on pour numéroter une liste ?

a+

Dernière modification par cristobal78 (Le 14/12/2011, à 00:12)


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#2 Le 11/12/2011, à 16:58

aduxas

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

Ce qui me paraît bizarre, c'est que ton wildcard risque de générer plusieurs résultats, alors que tu n'en veux clairement qu'un seul.  Regarde

grep -n fichier liste | sed 's/:.*//'

En gros, tu n'a pas besoin de numéroter la liste car grep le fait pour toi.

Dernière modification par aduxas (Le 11/12/2011, à 16:59)

Hors ligne

#3 Le 11/12/2011, à 17:07

aduxas

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

Dans un script bash:

var=$(grep -n fichier liste)
line=${var%%:*}

Hors ligne

#4 Le 11/12/2011, à 17:54

cristobal78

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

Salut aduxas

merci de ta réponse.

1-
Le wild card est nécessaire puisque je ne suis pas sur (comme dit dans le post initial) de l'orthographe du nom de fichier recherché.
C'est à la lecture de la liste et à elle seule que je vais me dire : "ah oui, bien sur,  c'est celui là (et pas l'autre)." et je sélectionne le bon fichier par le No de ligne moyennant un peu de commandes.

2-
grep -n fichier liste | sed 's/:.*//'

je ne comprends pas la syntaxe après grep -n

Il faut que je commence par un "find" avec wild caractere sinon je n'ai pas la matière surl aquelle travailler et je ne vois pas de find dans tes propositions.
J'ai essayé ceci :
find -iname "fic*" |grep -n "fic"
qui me liste avec numéro les fichiers dont le nom commence par "fic"  mais c'est un peu merdique comme résultat à traiter !

Peux tu m'en dire un peu plus stp !


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#5 Le 11/12/2011, à 17:57

Watael

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

salut,

select fichier in fichier_recherché*; do cetteVariable="$fichier"; break; done

edit: ajout d'un break pour sortir du select.

Dernière modification par Watael (Le 11/12/2011, à 18:49)


Connected \o/
Welcome to sHell. · eval is evil.

En ligne

#6 Le 11/12/2011, à 18:09

aduxas

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

La commande "find" trouve un fichier (ou plusieurs) dans une arborescence, donc sur le disque. La commande "grep" fouille le contenu d'un fichier donné (ou plusieurs).  Si tu veux trouver un  fichier sur le disque, et vérifier si son nom se trouve dans une liste, tu peux faire

find . -iname fichier -exec grep -ni {} liste \; 

Si une réponse est trouvée, tu peux en extraire le numéro de ligne avec "sed" ou l'édition bash comme montré.  Tout ce que ça fait, c'est enlever le texte qui se trouve après les deux points dans le résultat du "grep".  Ce qui reste, c'est le numéro de ligne dans la liste.

EDIT:  beuh, ma commande est fausse:  il faut d'abord extraire la racine du fichier

Dernière modification par aduxas (Le 11/12/2011, à 18:39)

Hors ligne

#7 Le 11/12/2011, à 18:43

Watael

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

salut aduxas,

je crois que tu n'as pas bien compris ce que veux cristobal78.

choisir le bon fichier dans la liste qui va m'apparaitre il faudrait  qu'elle soit numérotée

en fait, il voudrait que la sortie du find soit numérotée pour qu'il puisse choisir le fichier que la suite du script traîtera.

Si cristobal78 pouvait confirmer l'une ou l'autre de nos interprétations

Dernière modification par Watael (Le 11/12/2011, à 18:44)


Connected \o/
Welcome to sHell. · eval is evil.

En ligne

#8 Le 11/12/2011, à 18:53

aduxas

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

Je vois, Watael.  Tu penses qu'il veut simplement numéroter la liste de fichiers trouvés par "find" pour permettre à l'utilisateur d'entrer un choix.  On peut utiliser un grep redondant pour numéroter:

find -iname "fichier*" |grep -n "fichier"

  On peut changer le format du séparateur avec un petit coup de sed.

Dernière modification par aduxas (Le 11/12/2011, à 19:03)

Hors ligne

#9 Le 11/12/2011, à 19:06

Watael

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

ou nl, qui est fait pour.
mais puisque bash dispose d'une commande (select) prévue pour faire ce genre de chose, pourquoi se compliquer la tâche.
à find -iname, j'opposerai shopt -s nocaseglob

Dernière modification par Watael (Le 11/12/2011, à 19:06)


Connected \o/
Welcome to sHell. · eval is evil.

En ligne

#10 Le 11/12/2011, à 19:07

cristobal78

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

Eh oui cher watael, c"est toi qui a tout compris !!

"...en fait, il voudrait que la sortie du find soit numérotée pour qu'il puisse choisir le fichier que la suite du script traîtera...."

comme l'indiquait mon post :

"...choisir le bon fichier dans la liste qui va m'apparaitre il faudrait  qu'elle soit numérotée..."


Je vais regarder vos propositions et les tester dans mon script .


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#11 Le 11/12/2011, à 20:57

cristobal78

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

@watael et @aduxas

voilà ce que j'ai fait :
d'abord avec find je cherche les fichiers commençant par les caractères "pc2" (ce n'est qu'un exemple mais je le fais car je sais que j'ai 3 fichiers dont les noms commencent par ces caractères) et les mets dans un fichier appelé "filesfound"

sudo find -iname "pc2*" |grep -n "pc2" > filesfound

Note : je mets un sudo devant find car sinon il y a un message qui ne me sert à rien : find: "./.dbus": Permission non accordée et je n'ai trouvé que ça pour m'en débarraser  neutral

Ensuite je fais un cat de filesfound qui m'affiche ma liste de choix  numérotée:

cat filesfound

1:./mes_scripts/pc2pc_fic
2:./mes_scripts/pc2pc_fic2
3:./mes_scripts/pc2pc_rep

Maintenant avec la liste sous les yeux  je sais lequel des 3 fichiers apparus m'intéresse. Disons par exemple qu'ici c'est le 3-ème fichier qui est l'objet de toutes mes attentions.
Comme je ne veux que son nom je me débarrasse des caractères précédent le " : "

grep 3 filesfound |cut -d: -f2

./mes_scripts/pc2pc_rep

Ça y est ! J'ai récupéré le nom exact du fichier qui m'intéresse.
Maintenant que je sais que ça marche j'en profite pour créer tout de suite une  variable que j'appelle  "goodfile" dont la valeur est le nom du fichier qui m'intéresse :

goodfile=`grep 3 filesfound | cut -d: -f2`

Ca marche ! La preuve ?

echo $goodfile
./mes_scripts/pc2pc_rep

Conclusion j'ai ma solution.
J'ai à partir d'un nom approximatif pu obtenir la liste des fichiers ressemblants au modèle "pc2" et j'ai pu faire une variable avec le nom de celui que je voulais.
Ca paraitra sans doute "lourdingue" à certains.
Si vous avez plus simple ou plus sur ou plus rapide ou les 3 à la fois je vous lirai avec joie  smile

Dernière modification par cristobal78 (Le 11/12/2011, à 21:07)


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#12 Le 11/12/2011, à 21:17

Watael

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

shopt -s nocaseglob globstar
select fic in **/pc2* Quitter; do goodfile="$fic"; break; done
echo "$goodfile"

Connected \o/
Welcome to sHell. · eval is evil.

En ligne

#13 Le 12/12/2011, à 00:01

cristobal78

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

qd je lance man shopt  je n'ai pas de manuel.
Qu'est ce que shopt ????


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#14 Le 12/12/2011, à 01:03

aduxas

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

C'est sous man bash.

Hors ligne

#15 Le 13/12/2011, à 00:33

cristobal78

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

Merci donc à mes 2 coach  smile

Finalement cela m'a permis de réaliser un programme qui me permet d'envoyer d'un pc à l'autre (j'en ai 3 derrière un routeur wifi).
Cela m'a permis de creuser certaines instructions et me casser la tête sur la syntaxe  mad afin de contrôler les entrées de toutes sortes et faire en sorte que, malgré des erreurs de saisie de l'utilisateur désinvolte, le script ne plante pas (?)
Bien sur openssh server et client sont installés sur les 3 PC et les parefeu désactivés.

#!/bin/bash
# But  = Transférer un fichier donné d'un PC source vers un PC cible du réseau local
# Syntaxe =  pc2pc_fic   2_derniers_chiffres_de_l'adresse_IP_du_pc_cible    nom_user
# Remarque  =  le nom du fichier à transférer est choisi de façon interactive
# Le réseau local comprend 3 PC derrière un (routeur wifi) d'adresses : ...11, ...12 et ...13
# Les 2 user possibles sont "jcc" et "dan"

clear
ip=$1
user=$2
erreur="#############################   E R R E U R   ###################################################"
trait="##############################################################################################"

if [ $# != 2 ]
    then
    echo
    echo $erreur
    echo ""
    echo " Il faut 2 arguments à droite du nom du fichier $0."
    echo ""
    echo " La bonne syntaxe est : "
    echo " $0 2_derniers_chiffres_de_l'adresse_IP_du_pc_cible   nom_user  "
    echo ""
    echo " Exemple : $0  13   jcc"
    echo " qui va transfèrer un fichier sur le pc cible d'adresse ip '192.168.0.13', chez le user  'jcc'. "
    echo ""
    echo " Relancer le programme $0    avec ses 2 arguments."
    echo ""
    echo $trait
    echo
    exit 1
fi

 if  [[  $ip != 11  &&  $ip != 12 &&  $ip != 13  ]]            # vérifie que l'ip est 11, 12 ou 13
    then
    echo $erreur
    echo ""
    echo "  Relancer le programme $0     avec la bonne adresse ip "
    echo $trait
    echo ""
    exit 1
fi

 if  [[  $user != "jcc"  &&  $user != "dan"  ]]            # vérifie que le user est soit jcc soit dan
     then
    echo $erreur
    echo "  Relancer le programme $0 avec le bon user "
    echo ""
    echo $trait
    echo
    exit 1
fi
 
# echo $trait
echo ""
echo -n " Entrer les premières lettres (au moins 4) du nom du fichier à transférer ---> "
# echo ""
#echo $trait
# echo ""
read fic
sudo find -name "$fic*" | grep -n "$fic*" > filesfound        # fait une liste des noms defichiers trouvés ressemblant au modèle et en numérote les lignes
if [ $? != 0 ]
    then
    echo $erreur
    echo "Fichier non trouvé"
    echo ""
    exit 1
fi

echo ""
cat filesfound
nbre_lignes=$(cat filesfound | wc -l)

echo ""
echo -n " Entrer le no de ligne correspondant au fichier à transférer (0 pour sortir)---> "
read numero

if [[  "$numero" -eq ""  ]]                            # sortie si choix = 0 ou appui sur "Entrée"
    then
    echo " Sortie du script "
    echo ""
    exit 1
fi

if [[  $numero -gt  $nbre_lignes  ]]
    then
    echo ""
    echo $erreur 
    echo " Numero de ligne incorrect "
    echo ""
    exit 1
fi

echo ""
goodfile=`grep $numero: filesfound | cut -d: -f2`        # met dans la variable "goodfile" le nom du fichier situé à la ligne commençant par " numéro: " 
ip_pc_cible=192.168.0.$ip                        # reconstitution de l'adresse ip complète
echo ""

 # z_venu_du_serveur est un répertoire qui ne sert qu'à réceptionner les tranferts de data. Evite le risque d'écrasement accidentels
 echo $trait
 echo ""
echo " Le fichier $goodfile va être transféré sur le PC d'adresse $ip_pc_cible dans le répertoire /home/jcc/z_venu_du_serveur"
echo""
scp -rp $goodfile  $user@$ip_pc_cible:/home/jcc/z_venu_du_serveur

echo $trait
echo ""
echo "* * * TRANSFERT TERMINÉ  * * * "
echo ""

Deux remarques enfin :
- J'avais commencé par find -iname et suis repassé en find -name car parfois ça foutait le bordel dans ma liste numérotée.
- J'ai parfois des doutes sur l'utilisation de "=" au lieu de "-eq" ou par exemple de -lt au lieu de < et d'ailleurs dans ce script j'ai du remplacer certains "=" par des "-eq" sinon ça m...dait.:)

Donc je suis preneur d'éclaircissements. smile

a+

Dernière modification par cristobal78 (Le 13/12/2011, à 00:44)


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#16 Le 13/12/2011, à 05:10

Watael

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

est-ce que je parle dans un puit sans fond, et surtout sans echo ?

Utiliser grep pour numéroter des lignes, c'est comme utiliser un marteau pour enfoncer une punaise : ça peut le faire ! mais est-ce bien utile ?
il y a un gnu coreutil : nl (comme numéroter_ligne), qui est fait exprés.

Pour moi, ce n'est pas la bonne façon de faire (trop de fichier temporaire, de cat, et de commandes externes), mais c'est ton script.

Quant à utiliser = ou -eq :
- si c'est du texte, c'est = (ou \<, ou \>, sinon le shell croit que c'est des redirections)
- si c'est des nombres, c'est -eq (et al.)
Si c'est des nombres, pourquoi ne pas se servir de l'évaluation arithmétique que propose bash ?
Entre double parenthèses, on revient aux symboles arithmétiques =, <, <=, >, >=, etc.

enfin, je m'arrêterai là, les doubles crochets ne sont (amha) à utiliser que si on a besoin de leurs propriétés avancées.


Connected \o/
Welcome to sHell. · eval is evil.

En ligne

#17 Le 13/12/2011, à 13:41

cristobal78

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

@watael

Watael a écrit :

est-ce que je parle dans un puit sans fond, et surtout sans echo ?
Utiliser grep pour numéroter des lignes, c'est comme utiliser un marteau pour enfoncer une punaise : ça peut le faire ! mais est-ce bien utile ?
il y a un gnu coreutil : nl (comme numéroter_ligne), qui est fait exprés.

Je sens comme de l'agacement dans ta réponse smile
Voici l'echo remonté du puit.

- Tu m'as proposé shopt sans explications et d'ailleurs je n'ai absolument pas compris en quoi shopt pouvait m'aider malgré un passage sur le man.
- Nous en sommes au post No. 16 et tu me parles maintenant de gnu coreutils comme de la solution miracle.
- La cde qui m'a bien servi c'est find -iname "fichier*" |grep -n "fichier" .
  Au moins celle là je l'ai comprise et j'ai pu la mettre dans mon script, même si ce n'est pas la solution la plus élégante.
  Mon script est un proto qui marche. Je l'affinerai au fur et à mesure que je maitriserai plus d'outils astucieux et puissants.


Pour moi, ce n'est pas la bonne façon de faire (trop de fichier temporaire, de cat, et de commandes externes), mais c'est ton script.

C'est en faisant des scripts qu'on apprend à faire des scripts.
A la lecture du mien tu dois bien te rendre compte que mes connaissances dans ce domaine sont celles d'un débutant qui ne maitrise -et encore- que quelques outils d'où mes questions auxquelles tu a d'ailleurs apporté quelques réponses plus bas et pour lesquelles je te remercie :


Quant à utiliser = ou -eq :
- si c'est du texte, c'est = (ou \<, ou \>, sinon le shell croit que c'est des redirections)
- si c'est des nombres, c'est -eq (et al.)
Si c'est des nombres, pourquoi ne pas se servir de l'évaluation arithmétique que propose bash ?
Entre double parenthèses, on revient aux symboles arithmétiques =, <, <=, >, >=, etc.

enfin, je m'arrêterai là, les doubles crochets ne sont (amha) à utiliser que si on a besoin de leurs propriétés avancées.

- si c'est des nombres, c'est -eq (et al.)"
---> que veux tu dire par (et al.)    ???

" Entre double parenthèses, on revient aux symboles arithmétiques =, <, <=, >, >=, etc."
---> j'aurai  été ravi que tu rajoutes un petit exemple smile

"...les doubles crochets ne sont (amha) à utiliser ..."
---> ça veut dire quoi "amha " ???


Accessoirement :
Y a t il un bon site (ou sites) que tu puisses me recommander pour en apprendre plus sur le bash que je n'ai jusqu'ici appris qu'en regardant et en testant des scripts écrits par d'autres.

a+


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#18 Le 13/12/2011, à 15:35

Watael

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

et al. = et alii
c'est du latin, ça veut dire «et les autres»; soit, -ne -le -ge et autres tests numériques (voir: help test)

les doubles parenthèses :

variable=2
((variable++))
echo $variable
3
if (( variable > 2 )); then echo "$variable est supérieur à 2"; fi

et cætera smile

amha = «à mon humble avis»

nl est simple d'utilisation

find -name "$fic*" | nl

man nl pour donner l'aspect que tu veux.

shopt active, ou désactive des options du shell.
nocaseglob et globstar sont en général désactivées. man bash pour voir ce qu'elles font.

une recommandation ? l'Advanced Bash Scripting
à confronter impérativement aux pratiques actuelles.

de la pratique, et, optimiser autant que possible.
le golf (lol), à la "perl golf" : trouver les solutions les plus concises.

et ne pas hésiter à poser des questions.


bonne continuation.

je n'ai rien oublié ?


Connected \o/
Welcome to sHell. · eval is evil.

En ligne

#19 Le 14/12/2011, à 00:12

cristobal78

Re : (résolu) Choisir un mot dans une liste numérotée par son no. de ligne

Merci
et merci pour l'advanced bash scripting : là j'en ai pour des mois !!

Au passage je vais mettre mon post #1 en résolu.


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne