我有一个巨大的.txt
文件(15 GB),拥有近3000万行。
我想根据4th column.
将其行放到不同的文件中unique
列的4th
列在2 million.
附近
file1.txt
1 10 ABC KK-LK
1 33 23 KK-LK
2 34 32 CK-LK,LK
11 332 2 JK@
11 23 2 JK2
现在,我可以将这些行分隔到相同文件夹中的不同文件,如下所示:
awk '{ print $0 >> $4"_sep.txt" }' file1.txt
它会导致4
个不同的文件:
KK-LK_sep.txt
1 10 ABC KK-LK
1 33 23 KK-LK
和
CK-LK,LK_sep.txt
2 34 32 CK-LK,LK
和
JK@_sep.txt
11 332 2 JK@
最后,
JK2_sep.txt
11 23 2 JK2
我想要的是,不要将200万个文件放在一个文件夹中,将它们分成20个不同的文件夹。我可以将文件夹设为folder1,2,3 ....:
mkdir folder{1..20}
通过以下答案,我认为像下面的代码可能有用:
#!/bin/env bash
shopt -s nullglob
numfiles=(*)
numfiles=${#numfiles[@]}
numdirs=(*/)
numdirs=${#numdirs[@]}
(( numfiles -= numdirs ))
echo $numfiles
var1=$numfiles
awk -v V1=var1 '{
if(V1 <= 100000)
{
awk '{ print $0 >> $4"_sep.txt" }' file1.txt
}
else if(V1 => 100000)
{
cd ../folder(cnt+1)
awk '{ print $0 >> $4"_sep.txt" }' file1.txt
}
}'
但是,如果有folder1
文件,我怎么能把它作为循环并停止累加到100.000
,然后开始向folder2
添加文件等等?
答案 0 :(得分:3)
也许这就是你想要的(未经测试,因为你的问题不包括我们可以测试的例子):
awk '
!($4 in key2out) {
if ( (++numKeys % 100000) == 1 ) {
dir = "dir" ++numDirs
system("mkdir -p " dir)
}
key2out[$4] = dir "/" $4 "_sep.txt"
}
{ print > key2out[$4] }
' file1.txt
这依赖于GNU awk来管理内部打开文件的数量。对于其他awks,您需要将最后一行更改为{ print >> key2out[$4]; close(key2out[$4]) }
或以其他方式处理有多少同时打开的文件,以避免出现“过多的打开文件”错误,例如:如果您的$ 4值通常组合在一起然后比在每次写入时打开和关闭输出文件更有效,那么您可以在$ 4值更改时执行此操作:
awk '
$4 != prevKey { close(key2out[prevKey]) }
!($4 in key2out) {
if ( (++numKeys % 100000) == 1 ) {
dir = "dir" ++numDirs
system("mkdir -p " dir)
}
key2out[$4] = dir "/" $4 "_sep.txt"
}
{ print >> key2out[$4]; prevKey=$4 }
' file1.txt
答案 1 :(得分:0)
count += !keys[$4]++;
bucket=count/100000;
ibucket=int(bucket);
ibucket=ibucket==bucket?ibucket:ibucket+1;
folder="folder"ibucket