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