[awk] découper un fichier en plusieurs fichiers
RésoluDIE -
Bonjour à tous et toutes
Je tourne en rond sur un script qui doit etre 100% en awk, mais je me demande si c'est possible finalement. J'ai essayé avec chatGPT mais il me sort n'importe quoi :-(
Voici mon problème :
- Dans le fichier suivant, je veux créer un nouveau fichier à chaque fois que l'on rencontre le mot PAGE dans le fichier d'entrée. La ligne contenant ce mot PAGE est reportée au début du fichier nouvellement créé.
- Si quelque part dans le fichier, après le mot PAGE, on trouve le mot NIR, alors la variable NIR est corrigée en conséquence et est utilisée pour nommer ce fichier. Le fichier est porte le comme nom la valeur de la variable NIR, suivie de l'extension ".txt".
Exemple :
- Fichier d'entrée :
totot
titi PAGE
tata
tata
dfdf fdf NIR un deux troix quatre
tata
dfdfd
dfdfdf dfdf PAGE
dfd
fdfdfd
dfdf
dfddfdfdf NIR one two three four five
dfdf
df PAGE
dfdf NIR dfdf
dfdfd
Résultat attendu :
- Le premier fichier créé s'appelle un.txt et contient :
titi PAGE
tata
tata
dfdf fdf NIR un deux troix quatre
tata
dfdfd
Le deuxième fichier créé s'appelle one.txt et contient :
dfdfdf dfdf PAGE
dfd
fdfdfd
dfdf
dfddfdfdf NIR one two three four five
dfdf
- Le troisième fichier créé s'appelle dfdf.txt et contient :
df PAGE
dfdf NIR dfdf
dfdfd
Merci d'avance
Windows / Firefox 122.0
- [awk] découper un fichier en plusieurs fichiers
- Fichier bin - Guide
- Fichier epub - Guide
- Comment réduire la taille d'un fichier - Guide
- Fichier rar - Guide
- Fichier .dat - Guide
4 réponses
hello
essayer
$ awk 'BEGIN {while(getline < "fichier")if($0 ~ /NIR/)for(n=1; n<=NF; n++)if($n ~ /NIR/)t[++f]=$(n+1)} /PAGE/ {a=t[++x] ".txt"} a {print $0 > a }' fichier $ $ more *txt :::::::::::::: dfdf.txt :::::::::::::: df PAGE dfdf NIR dfdf dfdfd :::::::::::::: one.txt :::::::::::::: dfdfdf dfdf PAGE dfd fdfdfd dfdf dfddfdfdf NIR one two three four five dfdf :::::::::::::: un.txt :::::::::::::: titi PAGE tata tata dfdf fdf NIR un deux troix quatre tata dfdfd
Bonjour,
J'ai réécris le message initial car certaines tournures étaient ambiguës et ça ne m'étonne pas que ChatGPT se soit pris les pieds dans le tapis (je ne pense pas d'ailleurs que ChatGPT soit capable de résoudre proprement un exercice de programmation non trivial, mais bref).
Quoi qu'il en soit, la définition du problème est incomplète :
- Que se passe-t-il (et doit-il se passer) si le mot clé NIR ne figure pas après le mot PAGE ?
- Crées-tu quand même un nouveau fichier ?
- Si oui, comment le nommes-tu ?
Bonne chance
ça marche SENSATIONNELLEMENT BIEN :)
mille merci
Je comprends pas comment marche le t[++f] par rapport au t[++x] si tu peux m'éclairer
Ce sont juste deux variables différentes, mais qui désignent dans les deux cas les index du tableau t.
- Dans un premier temps, au lancement du programme (bloc BEGIN), tu peuples un tableau t, et chaque fois que tu rencontres NIR, tu enregistres à l'index courant (noté f) le nom du futur fichier.
- Ensuite, tu traites le fichier à proprement parler, et à chaque fois que tu rencontres le mot PAGE, tu incrémentes un compteur (noté arbitrairement x) qui permet de récupérer dans t le nom du fichier.
J'en profite pour corriger une petite erreur dans la proposition #1, car si le fichier ne s'appelle pas "fichier", ça ne marchera pas. Bref, voici à quoi peut ressembler mon_script.awk :
#!/usr/bin/awk -f BEGIN { while (getline < ARGV[1]) { if ($0 ~ /NIR/) { for (n = 1; n <= NF; n++) { if ($n ~ /NIR/) { t[++f] = $(n + 1) } } } } } /PAGE/ { a = t[++x] ".txt" } a { print $0 > a }
Quelques remarques au passage :
- Le premier if (0 ~ /NIR/) est superflu. En pratique, il n'apporte rien. En effet, ce test oblige en lui-même à lire la ligne courante, qu'on va relire une seconde fois dans la boucle for qui suit. Cela signifie qu'on lit deux fois les lignes contenant NIR et une fois les lignes ne contenant pas NIR. Si on supprime ce test, chaque ligne n'est lue qu'une fois.
- Le bloc /PAGE/ permet de définir une variable a, qui correspond au fichier dans lequel on va écrire à présent. Si cette variable est définie, alors le 3e bloc est exécuté à chaque fois qu'on lit une nouvelle ligne, et il l'écrit dans le fichier a.
Une fois le fichier mon_script.awk écrit, pour le lancer :
awk -f mon_script.awk fichier.txt
Ou encore, on donne les droits en exécution au script, et grâce à la première ligne du script, ton shell sera qu'il doit utiliser awk -f :
chmod a+x mon_script.awk ./mon_script.awk fichier.txt
Bonne chance
en awk, un tableau commence à 1 (pas à 0 comme en C, par ex.) et une variable indéfinie vaut 0
à la première occurence de NIR f=0, donc t[++f] égale t[1], à la suivante t[2], etc
on relit le fichier
à la première occurence de PAGE x=0, donc t[++x] égale t[1], etc
on relit le tableau t contenant le nom de fichier à créer