2014-09-01 93 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;,或者給出想要從輸入文件中包裝的字符數。您可以將整個輸入文件分成許多塊。