2016-05-30 15 views
9

Tuyên bố từ chối trách nhiệm: Tôi đã đăng chéo số này qua số PerlMonks.Perl6: Ghi lại dòng mới của Windows bằng một chuỗi có regex

Trong Perl5, tôi có thể nhanh chóng và dễ dàng in ra các đại diện hex của dòng \r\n Windows theo phong cách kết thúc:

perl -nE '/([\r\n]{1,2})/; print(unpack("H*",$1))' in.txt 
0d0a 

Để tạo một file Windows-kết thúc trên Unix nếu bạn muốn kiểm tra, tạo ra một in.txt tệp với một dòng và dòng kết thúc. Sau đó: perl -ni -e 's/\n/\r\n/g;print' in.txt. (hoặc trong vi/vim, tạo tệp và chỉ cần :set ff=dos).

Tôi đã thử nhiều thứ trong Perl6 để làm điều tương tự, nhưng tôi không thể làm cho nó hoạt động bất kể tôi làm gì. Dưới đây là bài kiểm tra gần đây nhất của tôi:

use v6; 
use experimental :pack; 

my $fn = 'in.txt'; 

my $fh = open $fn, chomp => False; # I've also tried :bin 
for $fh.lines -> $line { 
    if $line ~~ /(<[\r\n]>**1..2)/ { 
     $0.Str.encode('UTF-8').unpack("H*").say; 
    } 
} 

Đầu ra 0a, cũng như:

/(\n)/ 
/(\v)/ 

Trước tiên, tôi thậm chí không biết nếu tôi đang sử dụng unpack() hoặc regex đúng cách. Thứ hai, làm cách nào để nắm bắt cả hai phần tử (\r\n) của dòng mới trong P6?

+2

Trong Perl5, tôi thích 'sprintf ("% v02X", $ s) '. Làm việc cho bất kỳ chuỗi nào, không chỉ các chuỗi byte. – ikegami

Trả lời

5

Perl 6 tự động tách bộ tách dòng cho bạn. Có nghĩa là nó không có ở đó khi bạn cố gắng thay thế.

Perl 6 cũng tạo các ký tự tổng hợp nếu có các ký tự kết hợp. vì vậy nếu bạn muốn có đại diện cơ bản 16 của đầu vào của bạn, hãy sử dụng mã hóa 'latin1' hoặc sử dụng các phương thức trên $*IN trả về một Buf.


Ví dụ này chỉ thêm CRLF vào cuối mỗi dòng.
(Dòng cuối cùng sẽ luôn luôn kết thúc với 0D 0A thậm chí nếu nó không có một dòng terminator)

perl6 -ne 'BEGIN $*IN.encoding("latin1"); #`(basically ASCII) 
    $_ ~= "\r\n"; #`(append CRLF) 
    put .ords>>.fmt("%02X");' 

Bạn cũng có thể tắt các hành vi autochomp.

perl6 -ne 'BEGIN { 
     $*IN.encoding("latin1"); 
     $*IN.chomp = False; 
    }; 
    s/\n/\r\n/; 
    put .ords>>.fmt("%02X");' 
1

Ok, vì vậy mục tiêu của tôi là (Tôi xin lỗi vì tôi không nói rõ khi tôi đăng câu hỏi) là tôi muốn đọc tệp, nắm bắt dòng kết thúc và ghi tệp lại bằng cách sử dụng các kết thúc dòng ban đầu (và không phải là kết thúc cho nền tảng hiện tại).

Tôi đã có bằng chứng về khái niệm hoạt động ngay bây giờ. Tôi rất mới với Perl 6, vì vậy mã có lẽ không phải là rất p6-ish, nhưng nó làm những gì tôi cần nó.

Mã thử nghiệm trên FreeBSD:

use v6; 
    use experimental :pack; 

    my $fn = 'in.txt'; 
    my $outfile = 'out.txt'; 

    # write something with a windows line ending to a new file 

    my $fh = open $fn, :w; 
    $fh.print("ab\r\ndef\r\n"); 
    $fh.close; 

    # re-open the file 

    $fh = open $fn, :bin; 

    my $eol_found = False; 
    my Str $recsep = ''; 

    # read one byte at a time, or else we'd have to slurp the whole 
    # file, as I can't find a way to differentiate EOL from EOF 

    while $fh.read(1) -> $buf { 
     my $hex = $buf.unpack("H*"); 
     if $hex ~~ /(0d|0a)/ { 
      $eol_found = True; 
      $recsep = $recsep ~ $hex; 
      next; 
     } 
     if $eol_found { 
      if $hex !~~ /(0d|0a)/ { 
       last; 
      } 
     } 
    } 

    $fh.close; 

    my %recseps = (
     '0d0a' => "\r\n", 
     '0d' => "\r", 
     '0a' => "\n", 
    ); 

    my $nl = %recseps<<$recsep>>; 

    # write a new file with the saved record separator 

    $fh = open $outfile, :w; 
    $fh.print('a' ~ $nl); 
    $fh.close; 

    # re-read file to see if our newline stuck 

    $fh = open $outfile, :bin; 

    my $buf = $fh.read(1000); 
    say $buf; 

Output:

Buf[uint8]:0x<61 0d 0a> 
+0

Tôi sẽ quay trở lại để đi qua giới thiệu/tài liệu, sau đó sau khi tôi thành thạo hơn, hãy kiểm tra lại với kiến ​​thức mới của tôi. – stevieb

+0

Là [newline.t] (https://github.com/perl6/roast/S16-io/newline.t) từ [nướng] (https://github.com/perl6/roast/blob/master/README) Hữu ích? – raiph

+0

Chắc chắn nhất! Cảm ơn nhiều. Trong thực tế, tôi thậm chí không nghĩ rằng để xem xét các tập tin thử nghiệm cho các ví dụ, nhưng toàn bộ bộ sẽ là một công cụ học tập to lớn. – stevieb

Các vấn đề liên quan