转置超过12 MB的文件时出现awk分段错误(内核转储)

转置超过12 MB的文件时出现awk分段错误(内核转储),awk,Awk,我正在使用此awk命令,当我的文件为11.5 MB时,它可以工作,但当我的文件为12 MB时,它不工作: awk -F ";" ' { for (f = 1; f <= NF; f++) a[NR, f] = $f } NF > nf { nf = NF } END { for (f = 1; f <= nf; f++) for (r = 1; r <= NR; r++)

我正在使用此awk命令,当我的文件为11.5 MB时,它可以工作,但当我的文件为12 MB时,它不工作:

awk -F ";" '
{ 
    for (f = 1; f <= NF; f++) 
        a[NR, f] = $f 
} 
NF > nf { 
    nf = NF 
} 
END { 
    for (f = 1; f <= nf; f++) 
        for (r = 1; r <= NR; r++) 
            printf a[r, f] (r==NR ? RS : FS) 
}' file > results
awk-F”;“'
{ 
对于(f=1;f nf{
nf=nf
} 
结束{

对于(f=1;f如果内存有限,可以将文件拆分为两个或多个部分,转置段并将结果粘贴在一起

例如,使用输入测试文件

1;2;3;4;5
6;7;8;9;10
11;12;13;14;15
16;17;18;19;20
我们分成两行,两行分别指向文件0和文件1

$ split -l 2 -da 1 file file_
运行您的awk命令以获取碎片

$ awk ... file_0 > file_0_tr
$ awk ... file_1 > file_1_tr
并使用相同的分隔符粘贴结果

$ paste -d';' file_0_tr file_1_tr

1;6;11;16
2;7;12;17
3;8;13;18
4;9;14;19
5;10;15;20

如果内存有限,可以将文件拆分为两个或多个部分,转置段并将结果粘贴在一起

例如,使用输入测试文件

1;2;3;4;5
6;7;8;9;10
11;12;13;14;15
16;17;18;19;20
我们分成两行,两行分别指向文件0和文件1

$ split -l 2 -da 1 file file_
运行您的awk命令以获取碎片

$ awk ... file_0 > file_0_tr
$ awk ... file_1 > file_1_tr
并使用相同的分隔符粘贴结果

$ paste -d';' file_0_tr file_1_tr

1;6;11;16
2;7;12;17
3;8;13;18
4;9;14;19
5;10;15;20

您可以对每列处理一次文件,将每列转换为一行:

$ cat tst.awk
BEGIN { FS=OFS=";" }
NR==1 {
    for (i=2;i<=NF;i++) {
        ARGV[i] = ARGV[1]
        ARGC++
    }
}
FNR==1 { if (NR>1) print ""; fileNr++ }
{ printf "%s%s", (FNR>1 ? OFS : ""), $fileNr }
END { print "" }

$ cat file
a;b;c
d;e;f

$ awk -f tst.awk file
a;d
b;e
c;f
$cat tst.awk
开始{FS=OFS=“;”}
NR==1{
对于(i=2;i1)打印“”;fileNr++}
{printf“%s%s”,(FNR>1?OFS:),$fileNr}
结束{打印“”}
$cat文件
a、 b;c
d、 e;f
$awk-f tst.awk文件
a、 d
b、 e
c、 f

由于它读取输入文件NF次而不是一次,执行时间会更长,但它存储在内存中的所有文件名都是NF次,因此不会耗尽内存。

您可以对每列处理一次文件,将每列转换为一行:

$ cat tst.awk
BEGIN { FS=OFS=";" }
NR==1 {
    for (i=2;i<=NF;i++) {
        ARGV[i] = ARGV[1]
        ARGC++
    }
}
FNR==1 { if (NR>1) print ""; fileNr++ }
{ printf "%s%s", (FNR>1 ? OFS : ""), $fileNr }
END { print "" }

$ cat file
a;b;c
d;e;f

$ awk -f tst.awk file
a;d
b;e
c;f
$cat tst.awk
开始{FS=OFS=“;”}
NR==1{
对于(i=2;i1)打印“”;fileNr++}
{printf“%s%s”,(FNR>1?OFS:),$fileNr}
结束{打印“”}
$cat文件
a、 b;c
d、 e;f
$awk-f tst.awk文件
a、 d
b、 e
c、 f

由于它读取输入文件NF次而不是一次,执行时间会更长,但它存储在内存中的所有文件名都是NF次,因此不会耗尽内存。

您的操作系统是什么?awk的哪个版本?出现在mawk 1.3.3 1996年11月,版权(C)Michael D.BrennanIm使用linux ubuntuThat看起来像是一个非常古老的实现。试试gawk(GNU awk)你应该把你的问题包括在简洁、可测试的输入/输出示例中,让我们测试一下,以确保我们理解你要做的事情。顺便说一句,永远不要做
printfa[r,f]
或类似使用输入数据作为printf的第一个参数时,请始终执行
printf“%s”,a[r,f]
,这样当输入数据包含printf格式字符(如
%s
)时,它不会发生神秘/灾难性的故障。您的操作系统是什么?awk的哪个版本?出现在mawk 1.3.3 1996年11月3日,版权所有(C)Michael D.BrennanIm使用linux ubuntuThat看起来像是一个非常古老的实现。试试gawk(GNU awk)你应该把你的问题包括在简洁、可测试的输入/输出示例中,让我们测试一下,以确保我们理解你要做的事情。顺便说一句,永远不要做
printfa[r,f]
或类似使用输入数据作为printf的第一个参数,始终执行
printf“%s”,a[r,f]
相反,当您的输入数据包含printf格式字符(如
%s
)时,它不会神秘地/灾难性地失败。这是最好的解决方案,再次喜欢您的天赋
++
,又短又优雅这是最好的解决方案,再次喜欢您的天赋
++
,又短又优雅