2012-08-08 5 views
1

Je dispose d'un fichier avec les données ci-dessousFractionnement des fichiers basés sur un critère

.domain bag 
.set bag1 
bag1 
abc1 
.set bag2 
bag2 
abc2 
.domain cat 
.set bag1:cat 
bag1:cat 
abc1:cat 
.set bag2:cat 
bag2:cat 
abc2:cat 

Je veux diviser ce fichier en deux (bag1.txt et bag2.txt) en fonction de la valeur de consigne.

bag1.txt devrait ressembler à:

.domain bag 
.set bag1 
bag1 
abc1 
.domain cat 
.set bag1:cat 
bag1:cat 
abc1:cat 

bag2.txt devrait ressembler à:

.domain bag 
.set bag2 
bag2 
abc2 
.domain cat 
.set bag2:cat 
bag2:cat 
abc2:cat 

la ligne .domaine est commun pour les deux fichiers.

J'ai essayé la commande ci-dessous, mais cela ne fonctionne pas.

nawk '{if($0~/.set/){split($2,a,":");filename=a[1]".text"}if(filename=".text"){print|"tee *.text"}else{print >filename}}' file.txt 

Répondre

3

Une façon:

awk ' 
    BEGIN { 
     ## Split fields with spaces and colon. 
     FS = "[ :]+"; 

     ## Extension of output files. 
     ext = ".txt"; 
    } 

    ## Write lines that begin with ".domain" to all known output files (saved 
    ## in "processed_bags"). Also save them in the "domain" array to copy them 
    ## later to all files not processed yet. 
    $1 == ".domain" { 

     for (b in processed_bags) { 
      print $0 >> sprintf("%s%s", b, ext); 
     } 

     domain[ i++ ] = $0; 

     next; 
    } 

    ## Select output file to write. If not found previously, copy all 
    ## domains saved until now. 
    $1 == ".set" { 
     bag = $2; 
     if (! (bag in processed_bags)) { 
      for (j = 0; j < i; j++) { 
       print domain[j] >> sprintf("%s%s", bag, ext); 
      } 
      processed_bags[ bag ] = 1;    
     } 
    } 

    ## A normal line of data (neither ".domain" nor ".set"). Copy 
    ## to the file saved in "bag" variable. 
    bag { 
     print $0 >> sprintf("%s%s", bag, ext); 
    } 
' file.txt 

Exécuter commande suivante pour vérifier la sortie:

head bag[12].txt 

Sortie:

==> bag1.txt <==                                                        
.domain bag                                                         
.set bag1                                                          
bag1                                                           
abc1                                                           
.domain cat                                                         
.set bag1:cat                                                         
bag1:cat 
abc1:cat 

==> bag2.txt <== 
.domain bag 
.set bag2 
bag2 
abc2 
.domain cat 
.set bag2:cat 
bag2:cat 
abc2:cat 
+0

C'est ok.But peut-on généralise la part de lignes communes? S'il y a beaucoup de sacs? comme bag1 .... bag1000.how est-ce que je peux faire ceci? Le dossier réel que j'ai a beaucoup de sacs de bag1 à bag1000.instead d'impression >> bag1 pouvons-nous le faire simplement avec l'impression> *. txt (beaucoup de dossiers vides sont déjà présent dans le répertoire de bag1.txt à sac 1000.txt) – Vijay

+0

@peter: J'ai édité la réponse pour la généraliser. C'est entièrement commenté et vous pouvez voir si cela correspond à vos besoins parce que je ne comprends pas ce que vous voulez dire avec 'print >> * .txt' – Birei

Questions connexes