使用perl自动包装文本流

时间:2014-09-01 13:23:32

标签: perl

this question按字符折叠。根据{{​​1}}变量,这已经是一个不错的perl answer

我尝试制作一个$/(核心模块)自动换行解决方案,遗憾的是没有成功。

我的测试生成器是:

Text::Wrap

以上将生成一系列文字,如:

perl -E 'srand(1);for(;;){print join("",map{("a".."z")[rand 26]}1..(3+rand 10))," ";}'

例如将其运行为:

lvi aeztjjod ydp udqfa yixpkxsf acwdthqlnilr uvizrdwsjo hygoqon chstr jnoryfpco yfuip qxjgmxiviypz foyqoz zqvrce czwqb hsjzdgxsxlg pozstag mcnwksf lhshrqi ...

将获得包含以下字样的行:

perl -E 'srand(1);
for(;;){print join("",map{("a".."z")[rand 26]}1..(3+rand 10))," ";}' | fold -s

如何用perl实现这样的自动换行?

我的脚本是:

lvi aeztjjod ydp udqfa yixpkxsf acwdthqlnilr uvizrdwsjo hygoqon chstr jnoryfpco 
yfuip qxjgmxiviypz foyqoz zqvrce czwqb hsjzdgxsxlg pozstag mcnwksf lhshrqi fjy 
hqdeqnph ujulsh jtjcpzbhzw ujnnfom gujgiurptdla dtyoym ooyluqjyxhr nbo wcw
...

但是这只包装前1024个字符,并且不知道如何在同一行“继续”以获取结果,例如来自use 5.014; use warnings; use Text::Wrap; $Text::Wrap::columns=80; while( sysread(STDIN, my $buff,1024) ) { #using sysread for reading unbuffered data print wrap(undef,undef,$buff); } 命令。

编辑,刚刚意识到整个逻辑读取一个字符块是错误的,因为例如当单词从798开始并具有例如长度时,读取800个字符(乘以80)可能会产生错误的结果。 10个字符。在这种情况下,第一个读取将获得前2个字符,然后从单词中读取剩余的字符,但它将由空格分隔...

EDIT2 ...除非使用@ choroba答案中的技巧,将最后一行(不是完整行)与下一个输入缓冲区分开。

2 个答案:

答案 0 :(得分:4)

从包装文本中删除最后一条(可能更短)的行,将其添加到以下部分以便稍后包装:

#!/usr/bin/perl
use warnings;
use strict;
use Text::Wrap qw{ wrap };

# $Text::Wrap::break   = qr/\s/;
$Text::Wrap::columns = 80;

my $firstline = q();
while (sysread STDIN, my $buff, 1041) {
    my $wrapped = wrap(undef, undef, $firstline . $buff);
    $wrapped =~ s/\n(.*)$/\n/;
    my $lastline = $1;
    print $wrapped;
    $firstline = $lastline;
}

请注意,我保留$break的默认值,以获得与fold -s相同的输出。

答案 1 :(得分:0)

@novacik:简单的方法是使用所需数量的字符(如$/ = \80;$/ = \1024;)更改输入记录分隔符,或者从输入文件中提供要包装的字符数。您可以将整个输入文件分成许多块。