Bash 如何在每n个分隔符后插入\n而不带“0”;“内存问题”;在狂欢节上

Bash 如何在每n个分隔符后插入\n而不带“0”;“内存问题”;在狂欢节上,bash,shell,out-of-memory,Bash,Shell,Out Of Memory,我有一个序列大文件,用'ch'作为分隔符。 我们需要在每第40个字母处分成一条新的线 我们已经尝试过使用perl/cut命令,但是我们遇到了“内存不足”错误,因为它是一个巨大的文件,读/写是一次性发生的 那么我想要的是以下内容 在第40次删除时进行剪切,并写入/刷新文件,不保留在内存中,然后在接下来的40次中再次执行相同操作,以此类推。 这在Bash中可以实现吗 任何帮助都将不胜感激 编辑: 这是我们在PERL中使用的命令 perl -pe 's{Ç}{++$n % 40 ? $& :

我有一个序列大文件,用'ch'作为分隔符。 我们需要在每第40个字母处分成一条新的线

我们已经尝试过使用perl/cut命令,但是我们遇到了“内存不足”错误,因为它是一个巨大的文件,读/写是一次性发生的

那么我想要的是以下内容

在第40次删除时进行剪切,并写入/刷新文件,不保留在内存中,然后在接下来的40次中再次执行相同操作,以此类推。

这在Bash中可以实现吗

任何帮助都将不胜感激

编辑:

这是我们在PERL中使用的命令

perl -pe 's{Ç}{++$n % 40 ? $& : "\n"}ge' <file_name>
我想剪切(比如第三个分隔符到新行)并分配给变量或其他东西,然后将其刷新到文件中,以便清除内存。

预期产出

123ÇasfiÇsadf
test1Ç123Çasfi
sadfÇtest1Çmock
注意:这是一个巨大的序列文件。
我们可以使用上述命令实现所需的输出,但对于较大的文件,它会引发内存异常,因此我们希望刷新块。

如果Python是一个选项,下面是我建议的C代码的端口:

# -*- coding: latin1 -*-
import sys

def cvt(fdin, fdout, delim, count):
    curr = count
    while True:
        c = fdin.read(1)
        if c is None or c == '': break
        if c == delim:
            curr -= 1
            if curr == 0:
                curr = count
                c = '\n'
        dummy = fdout.write(c)

cvt(sys.stdin, sys.stdout, 'Ç', 3)
正如预期的那样:

echo“123杼asfi杼sadf杼test1杼asfi杼sadf杼test1杼mock杼data杼test1杼asfi杼sadf杼test1杼mock杼data
123ÇasfiÇsadf
测试1Ç123Çasfi
sadfÇtest1Çmock
数据测试1测试123
asfiÇsadfÇtest1
模拟数据

有点长,但是告诉Perl将
作为记录分隔符,而不是
\n
;然后,您可以在读取“行”时将它们连接起来,对它们进行批处理,并分组输出。(我的Perl已经过时了;可能有一种更简单的方法可以做到这一点。)

在脚本的开头,我们将
$/
从其默认值换行符更改为您的分隔符;现在,一个“行”被定义为一个以字符结尾的字符串。我们初始化一个计数器
$c
,以跟踪我们读取的行数,并定义一个子例程来输出变量
$out
中累积的行数,然后重置累加器和计数器

对于每一行输入,我们首先将该行附加到累加器,递增计数器,然后在计数器的值达到目标组大小时调用输出例程


最后,我们在输入结束时调用输出例程,以刷新累加器中的所有剩余行。

为什么标记为Java?我甚至会说:[Java]或[bash或[puthon]?x)抱歉。现在更正。您也不需要将整个文件保存在Perl内存中,只需要将块保存到下一个分隔符。IMHO,这是一个C程序非常简单的用例…
#include int main(){int N=40,C;int N=N;char delim='ch';而(EOF!=(C=getc()){if(C==delim){if(--N==0){N=N;C='\N'}putc(c);}返回0;}
非常感谢。工作起来很有魅力。如果您能对命令进行更多的解释让我理解,那就太好了。提前谢谢。
# -*- coding: latin1 -*-
import sys

def cvt(fdin, fdout, delim, count):
    curr = count
    while True:
        c = fdin.read(1)
        if c is None or c == '': break
        if c == delim:
            curr -= 1
            if curr == 0:
                curr = count
                c = '\n'
        dummy = fdout.write(c)

cvt(sys.stdin, sys.stdout, 'Ç', 3)
 perl -ne 'BEGIN {$/="Ç"; $c=0; sub d { chomp $out; print "$out\n"; $out=""; $c=0; }}
           $out .= $_; $c++; &d if $c == 3;
           END { &d }' tmp.txt