Как разбить один файл на несколько файлов, если повторный термин входит в столбец 1? - PullRequest
0 голосов
/ 21 марта 2019

У меня есть большое имя файла как file.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  

Так что я хочу вывод, например, если 1 повторится в первом столбце, то он должен разбить файл следующим образом: --

a.txt:

1  1.1  
2  1.2  
3  1.3  
4  1.4  
5  1.5 

b.txt:

1  2.1  
2  2.2  
3  2.3  
4  2.4 

c.txt:

1  2.5  
2  2.8  
3  3.1

Ответы [ 5 ]

1 голос
/ 21 марта 2019

Если вам не слишком важны имена файлов, тогда они могут быть просто числами

 awk '(NR==1)||($1<t) { close(f); f=sprintf("%0.5d",i++)}{print > f; t=$1}'
1 голос
/ 21 марта 2019

Решение вопроса ОП: Не могли бы вы попробовать следующее (где ОП упоминал в своем посте, что выходные файлы должны быть a.txt или b.txt и т. Д.). Так как OP не упомянул, как только все выходные файлы алфавитов были созданы, что должно произойти, поэтому я написал программу, в которой после 27-го появления 1 происходит повторное использование файлов из a и добавление к уже существующим файлам.

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


РЕДАКТИРОВАТЬ (решение из комментария ОП о том, что ОП хочет выходные файлы в формах 1.txt, 2.txt и т. Д.): В случае, если вы хотите создать выходные файлы, такие как 1.txt , 2.txt и т.д., затем попробуйте следующее. Всякий раз, когда 1 входит в 1-е поле, он начинает записывать вывод в новый выходной файл.

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

Добавление пояснения к вышеприведенной команде:

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.

Команда выше создаст 3 выходных файла (согласно вашим образцам) следующим образом:

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 

PS: Я позаботился об ошибке "слишком много файлов открыто", используя команду close(file) в программах.

0 голосов
/ 21 марта 2019

здесь альтернатива с 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 голосов
/ 21 марта 2019

Это может работать для вас (GNU csplit & parallel):

csplit -sz file '/^1 /' '{*}'
parallel mv ::: xx?? :::+ {a..z}.txt
0 голосов
/ 21 марта 2019

предположим, что вы можете использовать Python, попробуйте это:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...