J'ai un fichier texte que je dois ajuster pour pouvoir le saisir dans une base de données.

Cependant, le format du fichier est, bien que cohérent, pas vraiment utile lorsque l'on veut les mettre en tableaux.

allow any 123.123.123.1,2,3 22,443

Ce dont j'ai besoin après, c'est quelque chose comme

allow any 123.123.123.1 22
allow any 123.123.123.1 443
allow any 123.123.123.2 22
allow any 123.123.123.2 443
allow any 123.123.123.3 22
allow any 123.123.123.3 443

Parce que le fichier texte est assez ancien et plus de 1000 lignes (une des raisons pour lesquelles je veux le mettre dans notre base de données), il serait très risqué de le faire manuellement.

Existe-t-il un moyen rapide de le faire avec des outils de traitement de texte comme sed, tr, etc.?

0
Laurenz ebs 20 avril 2017 à 17:07

3 réponses

Meilleure réponse

Pourrait simplement utiliser l'expansion d'accolades

printf "%s\n" "allow any 123.123.123."{1,2,3}" "{22,443}


allow any 123.123.123.1 22
allow any 123.123.123.1 443
allow any 123.123.123.2 22
allow any 123.123.123.2 443
allow any 123.123.123.3 22
allow any 123.123.123.3 443

Pourrait utiliser perl pour générer et exécuter des crochets

perl -ne 's/[^\.\s]+,[,\S]+/{$&}/g;s/[^{}\n]+(?![^{]*})/"$&"/g;print `printf "%s\n" $_`' f
3
123 20 avril 2017 à 15:01

Je suis venu avec un script Awk comme suit, pour faire le travail pour vous.

#!/usr/bin/awk

{
    n1=split($3,arr1,".")
    n2=split(arr1[n1],arr2,",")
    n3=split($4,arr3,",")

    k=arr1[1]"."arr1[2]"."arr1[3]

    for(i=1;i<=n2;i++) {
        for(j=1;j<=n3;j++) {
            print $1,$2,k"."arr2[i],arr3[j]
        }
    }
}

Mettez-le dans un fichier appelé script.awk et exécutez-le comme

awk -f awkscript.awk file
allow any 123.123.123.1 22
allow any 123.123.123.1 443
allow any 123.123.123.2 22
allow any 123.123.123.2 443
allow any 123.123.123.3 22
allow any 123.123.123.3 443

L'idée est de diviser le contenu de $2 par . d'abord pour obtenir la dernière partie seule 1,2,3 accessible en tant que arr1[n], c'est-à-dire le dernier élément du tableau qui est formé après la scission. Ensuite, l'élément séparé par des virgules est maintenant divisé par , et stocké dans le tableau arr2 et de la même manière pour l'enregistrement $4. Une variable k est créée juste pour stocker les trois premiers éléments dans le premier split(), c'est-à-dire juste 123.123.123

Maintenant, une boucle est faite sur les éléments du tableau formés pour imprimer les éléments selon les besoins.

2
Inian 20 avril 2017 à 14:34

Juste pour le plaisir de sed (GNU sed version 4.2.1):

sed -E -fallow.sed | sort

Avec allow.sed:

s/^([^\n]+[^,[:digit:]])([[:digit:]]+(,[[:digit:]]+)*),([[:digit:]]+)([^\n]*)$/\1\2\5\n\1\4\5/;
:a;
s/^([^\n,]+[^,[:digit:]])([[:digit:]]+(,[[:digit:]]+)*),([[:digit:]]+)([^\n]*)\n(.*)$/\1\2\5\n\6\n\1\4\5/;
ta;
s/^([^,]+)\n(.*,.*)$/\2\n\1/;
ta;
  • Recherchez des groupes de nombres séparés par des virgules.
  • doubler la ligne
    • suppression des nombres avant la dernière virgule dans une copie
    • suppression du numéro après la dernière virgule dans l'autre copie
    • suppression de la dernière virgule dans les deux copies
  • commencer une boucle ici
  • faire la même chose pour ce qui est avant la première nouvelle ligne
  • garder ce qui se trouve après la première nouvelle ligne
  • boucle si quelque chose a été remplacé
  • déplacer une virgule entre les nouvelles lignes (le cas échéant) vers l'avant
  • boucle s'il y en avait une

Production:

allow any 123.123.123.1 22
allow any 123.123.123.1 443
allow any 123.123.123.2 22
allow any 123.123.123.2 443
allow any 123.123.123.3 22
allow any 123.123.123.3 443
1
Yunnosch 20 avril 2017 à 18:30