1
votes

comment diviser un fichier en plusieurs fichiers, si le terme répété vient dans la colonne 1?

J'ai un gros nom de fichier en tant que file.txt qui contient des données comme celle-ci:

1  2.5  
2  2.8  
3  3.1

Donc je veux une sortie comme celle-ci, si 1 répétition dans la première colonne, cela devrait diviser le fichier comme ceci : ---

a.txt:

1  2.1  
2  2.2  
3  2.3  
4  2.4 

b.txt:

1  1.1  
2  1.2  
3  1.3  
4  1.4  
5  1.5 

c .txt:

1  1.1  
2  1.2  
3  1.3  
4  1.4  
5  1.5  
1  2.1  
2  2.2  
3  2.3  
4  2.4   
1  2.5  
2  2.8  
3  3.1  


2 commentaires

sur quelle règle se fonde-t-il?


Bienvenue dans SO, veuillez poster vos efforts, ce que vous avez essayé jusqu'à présent, quelle erreur vous rencontrez en faisant cela.


5 Réponses :


1
votes

Solution pour la question de OP: Pourriez-vous s'il vous plaît essayer suivant (où OP a mentionné dans son message que les fichiers de sortie devraient être a.txt code > ou b.txt etc.). Puisque OP n'a pas mentionné une fois que tous les fichiers de sortie alphabets ont été créés ce qui devrait se passer, j'ai donc écrit un programme où une fois que la 27e occurrence de 1 se produit, il continuera à utiliser les fichiers de a et continuera à s'ajouter aux fichiers déjà existants .

cat 1.txt
1  1.1  
2  1.2  
3  1.3  
4  1.4  
5  1.5  
cat 2.txt
1  2.1  
2  2.2  
3  2.3  
4  2.4   
cat 3.txt
1  2.5  
2  2.8  
3  3.1 


EDIT (solution du commentaire de OP selon laquelle OP veut des fichiers de sortie dans 1.txt , 2.txt etc.): Si vous souhaitez créer des fichiers de sortie comme 1.txt , 2.txt etc. puis essayez de suivre. Chaque fois qu'un 1 arrive dans le premier champ, il commencera à écrire la sortie dans un nouveau fichier de sortie.

awk '                        ##Starting awk program here.
$1==1{                       ##Checking condition if $1(first field) of current line is equal to 1 then do following.
  close(file)                ##Using close awk function to close output file whose name is stored in variable named file.
  file=++count".txt"         ##Creating a variable named file whose value is increment variable count value with .txt string.
}                            ##Closing BLOCK for condition here.
{
  print > file               ##Printing all lines to output file whose names is stored in variable file here.
}
'   Input_file               ##Mentioning Input_file name here.

Ajout d'une explication pour la commande ci-dessus:

awk '$1==1{close(file);file=++count".txt"}  {print > file}'  Input_file

La commande ci-dessus créera 3 fichiers de sortie (selon vos exemples) comme suit:

awk '
BEGIN{
  split("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z",array,",")
}
$1==1{
  close(file)
  file=array[++count]".txt"
  count=count==26?0:count
}
{
  print >> file
}
'  Input_file

PS: J'ai résolu l'erreur "trop ​​de fichiers ouverts" en utilisant la commande close (file) dans le (s) programme (s).


4 commentaires

@ daizy123, que doit-il se passer si le compte de 1 dépasse 26 (nombre d'alphabets)? est-il nécessaire de le remettre à 1, veuillez nous le faire savoir.


en utilisant cette commande, cela me donne cette erreur: awk: r.txt crée trop de fichiers ouverts numéro d'enregistrement d'entrée 115601, fichier time_org.txt ligne source numéro 1


comment créer un fichier de nombres disons 1.txt, 2.txt, 3.txt ....... jusqu'à N.txt, car les données sont volumineuses dans mon fichier d'entrée. Ce n'était qu'un exemple de fichier


@ daizy123, au cas où vous auriez besoin de fichiers comme 1.txt etc alors essayez ma commande EDIT?



0
votes

Supposons que vous puissiez utiliser python, essayez ceci:

counter = 1
output = None
with open('file.txt', 'r') as input:
    while True:
        line = input.readline()
        if line is None or len(line) == 0:
            break
        if line[0] == '1':
            if output is not None:
                output.close()
                output = None
        if output is None:
            output = open(str(counter) + '.txt', 'w')
            counter = counter + 1
        output.write(line)


0 commentaires

1
votes

Si vous ne vous souciez pas trop des noms de fichiers, alors ils peuvent simplement être des nombres

 awk '(NR==1)||($1<t) { close(f); f=sprintf("%0.5d",i++)}{print > f; t=$1}'


1 commentaires

et si vous avez besoin de lettres alors f = sprintf ("% c.txt", 97+ (i ++)) .



1
votes

Cela pourrait fonctionner pour vous (GNU csplit et parallèle):

csplit -sz file '/^1 /' '{*}'
parallel mv ::: xx?? :::+ {a..z}.txt


0 commentaires

0
votes

voici une alternative avec bash

#!/bin/bash
count=96                                                 # char before 'a'
while read line; do                                      # loop over all lines
   tag=$(echo $line | cut -d " " -f1)                    # get line tagger
   if [ "$tag" == "1" ]; then                            # group change on 1
       let "count = count + 1"                           # count file
       filename="$(printf "\\$(printf %o $count)").txt"  # create filename
       >$filename                                        # initial file
   fi
   echo "$line" >> $filename                             # append to file
done < file.txt                                          # input from file.txt


0 commentaires