Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 在awk中将不同的行累积到不同的文件中_Linux_File_Awk - Fatal编程技术网

Linux 在awk中将不同的行累积到不同的文件中

Linux 在awk中将不同的行累积到不同的文件中,linux,file,awk,Linux,File,Awk,我有一个巨大的.txt文件(15GB),有将近3000万行 我想根据4列将其行放入不同的文件。并且unique第4列的number约为200万。 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

我有一个巨大的
.txt
文件(15GB),有将近3000万行

我想根据
4列将其行放入不同的文件。
并且
unique
第4列的
number约为
200万。

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

最后

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

  } 


}'
#/bin/env bash
shopt-s nullglob
numfiles=(*)
numfiles=${#numfiles[@]}
numdirs=(*/)
numdirs=${#numdirs[@]}
((numfiles-=numdirs))
echo$numfiles
var1=$numfiles
awk-V1=var1'{
如果(V1 100000)
{ 
cd../文件夹(cnt+1)
awk“{print$0>>$4”_sep.txt”}”file1.txt
} 
}'
但是,一旦
100.000
文件在
folder1
中,我如何使其成为一个循环,并停止向
folder2
中添加文件,等等?

类似的内容? 计算唯一密钥并在阈值后增加存储桶

count += !keys[$4]++; 
bucket=count/100000; 
ibucket=int(bucket); 
ibucket=ibucket==bucket?ibucket:ibucket+1;    
folder="folder"ibucket

也许这正是您想要的(未经测试,因为您的问题不包括我们可以测试的示例):

这依赖于GNU awk来管理内部打开的文件数量。对于其他AWK,您需要将最后一行更改为
{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

如果您不需要第一个文件夹中的第一个100k,第二个文件夹中的第二个100k,等等,您可以输出到
(NR%20)“/“$4”\u sep.txt”
我只需要共享第四列的行在同一个文件中,但是,当第一个文件夹已满时,此代码如何将文件定向到第二个文件夹?因此,我们计算唯一键,bucket具有文件夹数。但是,我将
awk'{print$0>>4“_sep.txt”}file1.txt
,它将产生一个错误:
bash:!键[:event not found
您需要将这些添加到脚本中。这是一个sniplet而不是完整的脚本。我正在尝试将文件重定向到不同的文件夹,但它会重新创建
“$4”\u sep.txt“
在每个文件夹中,它们有不同的行。我在我的答案中添加了另一种可能的解决方案,但在提问时,在问题中有一个可测试的示例确实很重要。我写的完全一样;)。唯一的区别是将numDirs设置为
numDirs=sprintf(“%0.4d”,numDirs+1)
。这使得它总是一个4位数的目录名,这使得浏览更容易。这是个好主意,但我会在分配给dir name变量时这样做:
dir=sprintf(“dir%04d”,numDirs)
count += !keys[$4]++; 
bucket=count/100000; 
ibucket=int(bucket); 
ibucket=ibucket==bucket?ibucket:ibucket+1;    
folder="folder"ibucket
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
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