2014-09-01 91 views
1

this question按字符折行。根据$/变量,这已经是一个不错的perl answer用perl包装文本流

我曾尝试为字词换行制作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 

将得到字包裹线如:

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 
... 

如何用perl实现这样的词语包装?

我的脚本是:

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); 
} 

但这仅OK包第1024个字符,不知道如何“继续”在同一行,以获得结果,如从fold -s命令。

编辑,刚刚实现比整个逻辑读一个字符块是错误的,因为例如,读取800个字符(乘以80)可能会给出错误的结果,当该单词从798开始并且具有例如10个字符。在这种情况下,第一次读取将获得前2个字符,并随后从该字中读取其余字符,但会被空格分隔...

EDIT2 ...除非使用从@ choroba的答案是将最后一行(不是全行)与下一个传入的缓冲区分开。

+0

是不是有一个原因,你正在使用'sysread'块大小为1024,而不是只使用普通的'readline'? – TLP 2014-09-01 13:49:15

+0

@TLP无法读取“行”,因为这里只有一行,并且由于它流式传输(又名“无限”长数据流)而无法读取它。 – novacik 2014-09-01 14:15:53

回答

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

+0

是的!这是诀窍!谢谢。 – novacik 2014-09-01 14:09:54

0

@novacik:简单的事情是将输入记录分隔符更改为所需数量的字符,如$/ = \80;$/ = \1024;,或者给出想要从输入文件中包装的字符数。您可以将整个输入文件分成许多块。