Script BASH / parcours tableau avec variable

Tags: #<Tag:0x00007f50a02d1098>

Bonjour à tous,

Je viens vers vous aujourd’hui pour vous demander un petit coup de pouce, je suis bloqué sur un script bash;

Je m’explique:

je fais des traitements de fichiers grâce a leurs noms en les comparant à une liste contenue dans un fichier différent, le format du nom de fichier est de type suivant:
dossier_année_mois_nom_prénom_serial.pdf

je récupère tous les éléments dans un tableau après avoir enlevé l’extension et remplacé les « _ » par des espaces.
mon problème est que la partie nom et prénom peuvent contenir plusieurs mots et je cherche à parcourir le tableau et a extraire les mots correspondants

voici mon code:

for n in *.pdf; do
f="$(basename "$n" .pdf)"     # enleve le chemin et l'extension du fichier
tbl=( ${f//_/\ } )           # remplce "_" par des espaces et mets dans un tableau
fin=${#tbl[@]}               # compte le nombre d'enregistrement dans le tableau    
fi=$((fin-1))    # fin du tableau en enlevant le serial

while IFS=, read -r first last mail; do # parcours le fichier csv 
if [ "${first^^}" == "${tbl[3]^^}" ] && [ "${tbl[@]:4:$fi}" == "$last" ]; then  # si le nom contenu dans le fichier correspond à la partie nom du fichier et que la suite correspond au prénom..
nom="${first^^}"
prenom="${last^}"
fi
done <  /chemin/vers/mon/csv

ce code ne fonctionne pas il ne parcours pas le tableau du 4ème au dernier, je ne sais pas si c’est la bonne approche, parce que je dois dupliquer la condition en décalant de 1 si le nom comporte 2 mots…

je vous remercie de votre aide.

Quand-même surprenant d’arriver à ne pas utiliser ni ‹ grep/awk/sed › dans un script qui parait bien compliqué pour faire une opération qui semble à priori extrêmement simple.
Ce qu’il manque pour tester concrètement:
1 - exemple de liste de fichiers .pdf.
2 - exemple de contenu du fichier csv.
3 - repréciser le résultat escompté

bonjour,

merci pour le retour, le problème est que je ne connais pas a l’avance le nombre de mots contenus dans la partie nom et prénom du fichier donc ca rend la comparaison plus difficile. cette partie du script provient d’un ensemble de plusieurs scripts, je ne sais pas comment l’aborder, j’ai tester plusieurs méthodes différentes mais aucune ne satisfait.

voici mon exemple de csv:

first, last, mail
DUPONT, Jean, jean.dupont@mail.tld
DE LA VEGA, Don Diego, dondiego.delavega@mail.tld

voici 2 fichiers pdf correspondants à mes enregistrements:

SOCIETEFICTIVE_2022_01_DUPONT_JEAN_0000001.pdf
SOCIETEFICTIVE_2022_01_DE_LA_VEGA_DON_DIEGO_000005.pdf

Le nom du fichier est déja formé, il est reçu telquel,
je ne peux donc pas isoler à l’avance le nom et prénom dans le nom du fichier d’où la comparaison avec une liste de nom et prénom, en commençant par le fait que le nom contienne un mot, puis 2 …
je déduis ensuite le prénom en me décalant de 1 dans le champ du fichier jusqu’au dernier pour en déduire le prénom.

en testant que sur le nom ça fonctionne mais le traitement est faussé si 2 personnes ont le même nom de famille

Investigation à l’arrache.
La syntaxe nom/prénom n’étant pas homogène, le plus simple semble de concaténer nom+prénom pour la recherche.

ls *.pdf

SOCIETEFICTIVE_2022_01_DE_LA_VEGA_DON_DIEGO_000005.pdf  SOCIETEFICTIVE_2022_01_DUPONT_JEAN_0000001.pdf

cat fichier.csv

DUPONT, Jean, jean.dupont@mail.tld
DE LA VEGA, Don Diego, dondiego.delavega@mail.tld
for I in *.pdf ; do 
 cat fichier.csv |awk -F',' '{print $1,$2}' |tr -d ' ,'|grep -i $(echo $I |sed 's/.\{23\}//;s/_[0-9]*.pdf//;s/_//g')
done
DUPONTJean
DELAVEGADonDiego

Pour voir un peu ce que d’autres ont déjà proposé,
voir aussi : Script Bash/ parcours tableau avec variable / Terminal, scripts et ligne de commande / Forum Ubuntu-fr.org

Tu peux utiliser awk -F',' '{print $1,$2}' fichier.csv, à la place (ça fait toujours un fork & exec de moins). Almtesh avait commencé la chasse aux useless uses of cat dans un autre sujet, je poursuis son œuvre :yum:

1 J'aime

Si c’est du csv il y a un delimiteur de champ (usuellement la virgule).
si la virgule peut faire partie du contenu d’un champ alors il y a un delimiteur de contenu, usuellement les guillemets.

Donc on a toujours soit:
champ1,champ2,champ3
doit
"champ1","champ qui est nombreux",champ3

Donc on final on se moque de savoir ce qu’il y a dans les champs, on ne traite que les délimiteurs. C’est à ça que sert le csv.

Re-précision pour ceux qui chercheraient éventuellement à aider Headstorm de manière concrète.
La problématique n’est pas l’extraction d’un nom/prénom du fichier csv, mais qu’il n’existe aucune commande ou script linux qui permettra d’extraire sans ambiguïté nom et prénom de chaînes telles que DE_LA_VEGA_DON_DIEGO ou CHARLES_HUBERT_DE_LA_TRÉFONDIERE.

@Headstorm
C’est la raison pour laquelle utiliser la notion de tableau (array) dans ton script pour le nom de fichier n’est pas judicieux, puisque les colonnes noms/prénoms ne sont pas clairement labellisée/identifiée.

Autre proposition plus affinée relativement à mon débroussaillage initial:

for F in *.pdf ; do 
  while IFS=, read -r N P M; do
  if [[ "$(echo ${N^^}${P^^} |tr -d ' ')" == "$(echo $F |sed 's/.\{23\}//;s/_[0-9]*.pdf//;s/_//g')" ]]; then
  printf "%-10s%-10s%s\n" ${N// /} ${P// /} $M
  fi
  done < fichier.csv
done

DELAVEGA  DonDiego  dondiego.delavega@mail.tld
DUPONT    Jean      jean.dupont@mail.tld

En passant Don n’est pas un prénom mais un titre honorifique que l’on place devant le prénom :wink:

La couverture d’un des très bons livre que j’avais acheté,
regardez les noms des co-auteurs :

C’est juste pour dire que, en se basant simplement sur le nom des fichiers pdf, il sera difficile, voire impossible d’en extraire des informations fiables.

Imaginez, par exemple, que vous trouviez un fichier pdf nommé :

SOCIETEFICTIVE_2022_01_DE_LA_COQUILETTE_ANNE_SOPHIE_000005.pdf

ça ne sera pas évident du tout de pouvoir en extraire des informations fiables.

« Au passage », « c’est juste pour dire », qu’il n’y a vraiment pas besoin de lire un livre pour comprendre en 10s ce que j’ai déjà précisé, puis reprécisé et qui parait évident.

@Zargos

Le problème ne vient pas du CSV, le problème est de fractionner les champs du nom du fichier.

Bonjour @Verner

Merci pour le temps passé et pour la solution à mon problème que j’avais partiellement contourné par des boucles mannuelles, comme expliqué sur un autre forum où j’ai posé la même question
forum ubuntu-fr.org → Script Bash/ parcours tableau avec variable → message #14

ton approche est la meilleure dans mon cas et elle s’applique parfaitement.

@MicP a soulevé un problème avec les similitudes de nom prenom, j’ai donc ajouté une condition de contrôle sur la place du nom en recoupant avec les adresses mail associées, je le remercie également pour son temps et ses précieux conseils :slight_smile:

Merci à @Zargos @Sputnik93 également pour votre temps et votre contribution.

Je pensais à une autre possibilité (peut-être complémentaire) :

Il doit sans doute y avoir des informations plus précises dans le document pdf,
et si le contenu du fichier pdf n’est pas qu’une simple image d’un document scanné,
on peut convertir le document pdf en document au format texte.

Avec un peu de chance, on pourrait y trouver quelques lignes du genre :

Nom    : De la Coquillette
Prénom : Anne Sophie

et ces informations permettraient de différencier le nom du prénom.

Mais bon, je rêve peut-être…

Merci du retour, bien que je n’avais pas compris que tu avais ouvert plusieurs sujets dans différents forums, avec les mêmes intervenants.
J’ai utilisé exclusivement les informations que tu as fournies dans ce forum (ça me semble logique).
Dans la clarification initiale que j’avais demandée, tu n’as nul-part informé d’un problème de doublons.
Supposant que tu traitais peut-être des fichiers de plusieurs milliers de lignes, il est évident que la probabilité de doublons devait être anticipée en amont de ton script.

Je suis au regret de t’annoncer qu’étant donné que tu n’as ni la maîtrise du nommage des fichiers pdf, ni du contenu du csv, il est impossible de garantir une fiabilité globale à 100% de tes opérations.
Chaque doublon de nom/prénom a une probabilité d’erreur 1/2, voir pire si X répétitions (pas terrible), et chaque doublon demandera une vérification ultérieure.

Comment peux-tu appairer à postériori ‹ place du nom › et ‹ mail associé ›.
Je ne sais pas dans quel forum tu as évoqué et explicité ça, mais je ne comprends pas, ça me parait bien vague puisque justement, je ne vois pas comment.

Dans l’état actuel, en ajoutant un fichier «  SOCIETEFICTIVE_2022_01_DUPONT_JEAN_0000024.pdf » , et une ligne « DUPONT, Jean, jean.dupont2@mail.tld » dans le fichier.csv, voilà ce qui sortira (avec une variante de mon script précédent / même concept).

while read F ; do
 while IFS=, read N P M ; do
  grep -ioq $(tr -d '_' <<< ${F%_*}) <<< ${N// /}${P// /} && \
  printf "%-10s%-10s%28s  %s\n" "$N" "$P" $M ${F%\.*}
 done < fichier.csv
done <<< $(ls *.pdf |sed 's/.\{22\}_//')

output:

DE LA VEGA Don Diego  dondiego.delavega@mail.tld  DE_LA_VEGA_DON_DIEGO_000005
DUPONT     Jean             jean.dupont@mail.tld  DUPONT_JEAN_0000001
DUPONT     Jean            jean.dupont2@mail.tld  DUPONT_JEAN_0000001
DUPONT     Jean             jean.dupont@mail.tld  DUPONT_JEAN_0000024
DUPONT     Jean            jean.dupont2@mail.tld  DUPONT_JEAN_0000024

Bonjour à tous, j’ai lu le post et j’aimerais juste avoir quelque précisions sur le script
que signifie ${first^^} le ^^ dans les curly , je trouve rien comme explication la dessus

Bonjour

Voir le manuel de l’interpréteur de commandes bash
en lançant la ligne de commande suivante :

man --pager='less -p "paramètre\^motif"' bash

Ou, si besoin, la version originale du manuel (non traduite) :

LANG=C man --pager='less -p "parameter\^pattern"' bash

Quelques exemples :

michel@deb1104:~$ maVar="DEBIAN"
michel@deb1104:~$ 
michel@deb1104:~$ echo ${maVar,}
dEBIAN
michel@deb1104:~$ 
michel@deb1104:~$ echo ${maVar,,}
debian
michel@deb1104:~$

michel@deb1104:~$ maVar="debian"
michel@deb1104:~$ 
michel@deb1104:~$ echo ${maVar^}
Debian
michel@deb1104:~$ 
michel@deb1104:~$ echo ${maVar^^}
DEBIAN
michel@deb1104:~$ 

Je te remercie

C’est avec plaisir.

et j’en profite pour te souhaiter la bienvenue sur le forum debian-fr.org :slight_smile:

Super accueil, ça fait plaisir.
J’espère bientôt donner ma contribution :slight_smile: