我的大文件名称为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
这可能对您有用(gnu csplit& Parallel):
csplit -sz file '/^1 /' '{*}'
parallel mv ::: xx?? :::+ {a..z}.txt
如果您不太关心文件名,那么它们只能是数字
awk '(NR==1)||($1<t) { close(f); f=sprintf("%0.5d",i++)}{print > f; t=$1}'
op的问题解决方案:
您可以尝试以下(在他/她的帖子中提到的OP,输出文件应为 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
edit(从OP的评论中的解决方案,OP希望在1.txt
,2.txt
等表单中输出文件):,以防您要创建1.txt
,2.txt
等创建输出文件,然后尝试关注。每当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)
命令来照顾"打开过多的文件"错误。
假设您可以使用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)
在这里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