Sed/awk pour lier 2 fichier plats

Résolu/Fermé
Utilisateur anonyme - 12 juil. 2010 à 23:03
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 - 28 juil. 2010 à 16:04
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
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:

5 réponses

dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
13 juil. 2010 à 12:35
hello
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));
$ 
3
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
13 juil. 2010 à 12:56
Salut,

C'est plutôt un grand coup ;-)
0
Utilisateur anonyme
13 juil. 2010 à 14:35
Bon, laissez moi encore un moment pour comprendre.
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.
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
13 juil. 2010 à 15:06
comme on lit les 2 fichiers ensemble depuis stdin, NF < 2 est vrai quand on traite fichier1 et NF > 2 quand on traite fichier2
0
Utilisateur anonyme
13 juil. 2010 à 15:35
Les deux fichiers entrent comme deux champs et NF correspond alors à leur numero de champs, c'est bien ça ?

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 ?
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
13 juil. 2010 à 15:48
Salut,

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
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 894
13 juil. 2010 à 07:44
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 ?
0
Utilisateur anonyme
13 juil. 2010 à 09:10
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.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
13 juil. 2010 à 09:19
Salut,

Ca sera pas plus facile de donner un exemple concret en utilisant tes fichiers?
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
13 juil. 2010 à 09:22
Re,

Si j'ai bien compris, par exemple si on prends la tab02 tu dois obtenir

CREATE TABLE tab02 (champ1 Date( 08), champ2 Number (05));

?!
0
Utilisateur anonyme
13 juil. 2010 à 09:40
C'est tout à fait ça, lami20j.
Et j'ai évité de donner un exemple "réèl" parce que les noms des tables / champs sont en fait des codes alphanumeriques beaucoup moins compréhensibles que tab01 ou champ3.
(pour donner l'exemple que j'ai sous les yeux : table TR35B)
0
Utilisateur anonyme
13 juil. 2010 à 09:21
c'est ce qu'à fait nnj99
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
13 juil. 2010 à 09:35
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.
0