1

尽管我很震惊,但我在任何地方都找不到这个,而且我的 bash 技能仍然低于标准。

我有一个素数的文本文件:

2\n
3\n
5\n
7\n
11\n
等等...

我想提取 2^32 (4294967296) 下的所有素数加上一个额外的素数,并将这些素数保存到以相同方式格式化的自己的文本文件中。此外,到目前为止,我的文件刚刚超过 13 亿行,因此在限制之后停止是理想的。

更新:问题。

bash 脚本已经在这 11 个数字中循环了很长一段时间,而我没有注意到:

4232004449
4232004479
4232004493
4232004509
4232004527
4232004533
4232004559
4232004589
4232004593
4232004613
004437

更奇怪的是,我 grepped primes.txt(原版)和“^004437”无处可寻。这是bash的某种限制吗?

更新:解决方案

这似乎是某种限制,我真的不知道是什么。我重新选择 perl 脚本作为我的答案,因为它不仅可以工作,而且它在约 80 秒内从零创建了约 2GB,并包含了额外的素数。去这里寻找 bash 错误的解决方案。

4

4 回答 4

4
$  perl -lne 'print; last if $_ > 2**32' < myprimes.txt > myprimes2.txt

为您提供输入的素数序列,直到超过 2**32 的一个素数,然后停止。不将源文件读入内存。

于 2012-12-06T04:30:35.973 回答
3

在 shell 中,无需将整个 13 亿个数字加载到内存中,您可以使用:

n=4294967296
last=0
while read number
do
    if [ $last -gt $n ]
    then break
    fi
    echo $number
    last=$number
done < primes.txt > primes2.txt

您也可能会丢失last变量:

n=4294967296
while read number
do
    echo $number
    if [ $number -gt $n ]
    then break
    fi
done < primes.txt > primes2.txt
于 2012-12-06T04:32:47.453 回答
2

这在 Bash 中很容易做到!只需 cat 文件 primes.txt 来读取它,遍历每个数字,检查该数字是否小于 2^32,如果是,则将其附加到 primes2.txt。

确切的代码如下。

#!/bin/bash

n=4294967296; # 2^32

for i in `cat primes.txt`
do
        if [ $i -le $n ]
        then
                echo $i >> primes2.txt;
        fi
done

或者您可以使用这个简单的 Python 解决方案,它不需要将整个文件加载到内存中。

new_primes = open('primes2.txt', 'a')
n = 2**32

[new_primes.write(p) for p in open('primes.txt', 'r') if int(p) < n]
于 2012-12-06T04:18:06.057 回答
0

我建议在 Perl 中做这样的事情:

编辑:嗯,这可能是用完所有 RAM 的阵列 - 这应该对您的资源更友好。

#!/usr/bin/env perl

use warnings;
use strict;

my $max_value = ( 2 ** 32);
my $input_file = 'primes.txt';
my $output_file = 'primes2.txt';

open( my $INPUT_FH, '<', $input_file )
    or die "could not open file: $!";

open ( my $OUTPUT_FH, '>', $output_file )
    or die "could not open file: $!";

foreach my $prime ( <$INPUT_FH> ) {
  chomp($prime);
  unless ( $prime >= $max_value ) { print $OUTPUT_FH "$prime","\n"; }
}
于 2012-12-06T04:11:10.380 回答