Sed/awk pour lier 2 fichier plats
Résolu
Utilisateur anonyme
-
dubcek Messages postés 18789 Date d'inscription Statut Contributeur Dernière intervention -
dubcek Messages postés 18789 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour,
Je débute en shell et on me confie un probleme qui ne semble pas avoir été posé ici. Il s'agit de lier deux fichiers texte représentant à eux deux, la structure d'une base de données(les tables, seulement).
Sur le premier (fichier1), j'ai
* Les 5 premier caractères correspondent au nom de la table (longueur fixe)
* Les champs sont écrits sur 6 caractères à partir de la colonne 11 (longueur fixe)
* Le reste (AAA, 999) sont des valeurs alphanumériques variables
Le second (fichier2) ?une forme un peu plus claire :
* Les séparateurs sont un peu tordus
* On récupere des informations sur le type des champs (N=Number, D=Date, C=Char)
* On récupere des informations sur la taille des champs (05, 08, 50 ...)
* Le fichier n'est pas trié / ordonné
* Le fichier présente des champs obsolètes (Tab01.champ4, par exemple)
* Les AAA et 999 sont toujours des valeurs alphanumériques variables
On me demande de récupérer les informations de chaque fichier afin de créer des requêtes sql "CREATE TABLE". Par exemple :
Je n'aurai pas trop de problème dans un autre langage mais on ne me laisse pas d'autre
choix que le script unix, dans lequel (et en dépit des tutos de jipicy) je reste débutant.
J'ai pensé commencer par un awk pour pouvoir mettre un programme (avec des boucles) derrière mais je suis de toute façon bloqué par l'entrée en jeu du second fichier. Je suis comme devant un puzzle et je n'arrive pas ?trouver de coin :(
Si vous pouviez assortir vos réponses de quelques explications (cheminement logique), ça m'éviterai peut être de venir vous rembeter par la suite. Merci.
Je débute en shell et on me confie un probleme qui ne semble pas avoir été posé ici. Il s'agit de lier deux fichiers texte représentant à eux deux, la structure d'une base de données(les tables, seulement).
Sur le premier (fichier1), j'ai
tab01999999champ19999AAA999 tab01999999champ29999AAA999 tab01999999champ39999AAA999 tab02999999champ19999AAA999 tab02999999champ29999AAA999 ...
* Les 5 premier caractères correspondent au nom de la table (longueur fixe)
* Les champs sont écrits sur 6 caractères à partir de la colonne 11 (longueur fixe)
* Le reste (AAA, 999) sont des valeurs alphanumériques variables
Le second (fichier2) ?une forme un peu plus claire :
AAA;;tab01;;champ2;;N;;05;;999;;AAA;;999 AAA;;tab01;;champ1;;D;;08;;999;;AAA;;999 AAA;;tab02;;champ2;;N;;05;;999;;AAA;;999 AAA;;tab02;;champ1;;D;;08;;999;;AAA;;999 AAA;;tab01;;champ3;;C;;50;;999;;AAA;;999 AAA;;tab01;;champ4;;N;;05;;999;;AAA;;999 ...
* Les séparateurs sont un peu tordus
* On récupere des informations sur le type des champs (N=Number, D=Date, C=Char)
* On récupere des informations sur la taille des champs (05, 08, 50 ...)
* Le fichier n'est pas trié / ordonné
* Le fichier présente des champs obsolètes (Tab01.champ4, par exemple)
* Les AAA et 999 sont toujours des valeurs alphanumériques variables
On me demande de récupérer les informations de chaque fichier afin de créer des requêtes sql "CREATE TABLE". Par exemple :
CREATE TABLE tab01 (champ1 Date (08), champ2 Number (05), champ3 Char (50));
Je n'aurai pas trop de problème dans un autre langage mais on ne me laisse pas d'autre
choix que le script unix, dans lequel (et en dépit des tutos de jipicy) je reste débutant.
J'ai pensé commencer par un awk pour pouvoir mettre un programme (avec des boucles) derrière mais je suis de toute façon bloqué par l'entrée en jeu du second fichier. Je suis comme devant un puzzle et je n'arrive pas ?trouver de coin :(
Si vous pouviez assortir vos réponses de quelques explications (cheminement logique), ça m'éviterai peut être de venir vous rembeter par la suite. Merci.
A voir également:
- Sed/awk pour lier 2 fichier plats
- Fichier bin - Guide
- Fichier epub - Guide
- Fichier rar - Guide
- Comment réduire la taille d'un fichier - Guide
- Fichier .dat - Guide
5 réponses
hello
un p'tit coup de awk
un p'tit coup de awk
$ cat f1.awk BEGIN {a["D"]="Date";a["N"]="Number";a["C"]="Char"} NF < 2 { x[substr($0,1,5), substr($0,12,6)]=1} NF > 2 && x[$3,$5] {y[$3]=y[$3] $5 " " a[$7] " ("$9"), "} END {for (n in y){sub(", $","",y[n]);print "CREATE TABLE",n,"(" y[n] ");"}} $ $ (cat fichier1 ; sort -t ";" -k 3 fichier2 ) | awk -F ";" -f f1.awk CREATE TABLE tab01 (champ1 Date (08), champ2 Number (05), champ3 Char (50)); CREATE TABLE tab02 (champ1 Date (08), champ2 Number (05)); $
Salut,
J'ai du mal à comprendre le rapport qui existe entre le fichier1 et le fichier2 !!??
Quels sont les critères qui unissent les 2 fichiers dans la requête à fournir ?
Si on s'en réfère à ton exemple, seul le fichier2 est utile pour écrire la requête, non ?
J'ai du mal à comprendre le rapport qui existe entre le fichier1 et le fichier2 !!??
Quels sont les critères qui unissent les 2 fichiers dans la requête à fournir ?
Si on s'en réfère à ton exemple, seul le fichier2 est utile pour écrire la requête, non ?
Bonjour jipicy,
le fichier #1 permet de savoir quels enregistrements du fichier #2 sélectionner : tab01.champ4 n'apparaît pas dans le fichier #1, il ne faut pas le retenir du fichier #2.
le fichier #1 permet de savoir quels enregistrements du fichier #2 sélectionner : tab01.champ4 n'apparaît pas dans le fichier #1, il ne faut pas le retenir du fichier #2.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Merci de répondre si vite.
Comme le dit qqchquicommenceparQ, le fichier 1 possede les tables, les champs et "l'ordre" dans/avec/pour (?) lequel on me demande de créér les champs.
Il est lié au fichier 2 (qui lui possède tout) par les informations "table" et "champs".
Dans le fichier 1, la table correspond au 5 premiers carracteres (donc je pense que que j'aurai un "cut -c0-5" quelque part), dans le fichier 2 c'est le deuxieme "champs" - ou du caractere 5 au carractere 10, puisqu'il n'y a pas qu'une façon de résoudre.A
Concernant les champs, on le trouve du carractere 11 à 16 pour le fichier 1 et en 3ème colonne dans le fichier 2.
Comme le dit qqchquicommenceparQ, le fichier 1 possede les tables, les champs et "l'ordre" dans/avec/pour (?) lequel on me demande de créér les champs.
Il est lié au fichier 2 (qui lui possède tout) par les informations "table" et "champs".
Dans le fichier 1, la table correspond au 5 premiers carracteres (donc je pense que que j'aurai un "cut -c0-5" quelque part), dans le fichier 2 c'est le deuxieme "champs" - ou du caractere 5 au carractere 10, puisqu'il n'y a pas qu'une façon de résoudre.A
Concernant les champs, on le trouve du carractere 11 à 16 pour le fichier 1 et en 3ème colonne dans le fichier 2.
C'est plutôt un grand coup ;-)
Je pensais que vous alliez proposer un sed et plein de pipes ; par chance, c'est un awk avec une suite d'instruction. Je devrais pouvoir le comprendre un peu plus facilement.
L'idée de faire un tableau de substitution est géniale. Je me voyais déjà faire une suite de s/ ou de tr.
Je continue mon exploration de cette solution et je reviens dès que j'ai compris pourquoi un utilise NF :)
Mais merci beaucoup, je pense que je vais pouvoir apprendre énormément grace à cet exemple.
Je ne comprends pas bien le fonctionnement de la lecture.
L'idée estde lire le fichier 1 ligne par ligne ; et pour chaque ligne du fichier 1, chercher la bonne ligne dans le fichier 2. Si les 2 fichiers sont ouverts en même temps par awk, peut etre conserver le numero de ligne ou on en était dans le fichier 2 (pour ne pas relire le fichier 2 (15k lignes) depuis le début à chaque fois).
J'ai compris le fonctionnement de x[$3,$5] ... c'est franchement pas mal aussi. Mais du coup, je ne comprends pas comment est faite la lecture des deux fichiers en simultanés
avec awk.
Des explications ?
ne comprends pas comment est faite la lecture des deux fichiers en simultanés
Ce n'est pas simultanés mais un après l'autre.
La lecture est faite avec cette commande (tu peux taper seulement ça pour voir)
cat fichier1 ; sort -t ";" -k 3 fichier2
et la sortie est lue par awk -F ";" -f f1.awk