2009-11-30 35 views
11

Theo mặc định, in perl \ r \ n trong môi trường win32. Làm thế nào tôi có thể ghi đè lên điều này? Tôi đang sử dụng perl để thực hiện một số thay đổi đối với một số mã nguồn trong một kho lưu trữ, và tôi không muốn thay đổi tất cả các ký tự dòng mới.Làm thế nào tôi có thể in chỉ một dòng mới unix trong Perl trên Win32?

Tôi đã thử thay đổi dấu phân tách bản ghi đầu ra nhưng không có may mắn.

Cảm ơn!

Edit: Wanted để bao gồm một mẫu mã - Tôi đang làm một tìm kiếm và thay thế trong một số tác phẩm mà theo một mô hình tương đối đơn giản như thế này:

#!/usr/bin/perl 
# test.pl 

use strict; 
use warnings; 

$/ = undef; 
$\ = "\n"; 
$^I=".old~"; 

while (<>) { 
    while (s/hello/world/) { 

    } 
    print; 
} 

này nên thay thế bất kỳ trường hợp của "hello "với" thế giới "cho bất kỳ tệp nào được truyền trên dòng cmd.

Chỉnh sửa 2: Tôi đã thử các binmode như đề xuất mà không cần bất kỳ may mắn ban đầu. Tôi đã nghiên cứu thêm một chút và thấy rằng $^I (biến đặc biệt chỉnh sửa tại chỗ) đã ghi đè binmode. Bất kỳ công việc xung quanh để vẫn có thể sử dụng chỉnh sửa tại chỗ?

Sửa 3: Như Sinan chỉ ra dưới đây, tôi cần thiết để sử dụng binmode ARGVOUT với $^I thay vì binmode STDOUT trong ví dụ của tôi. Cảm ơn.

+2

Nếu bạn thay đổi dấu phân tách bản ghi đầu ra, thì đó là điều duy nhất bạn có thể làm. Tôi đoán bạn đã phạm phải một số sai lầm khác (như không thực sự tách các dòng vào một cách chính xác, hoặc không chomping chúng). –

+0

Bạn có thể đưa ra ví dụ về một số mã in '\ r \ n' khi bạn không muốn? – Ether

+0

@ Sinan, tại sao bạn cho rằng tôi không sẵn sàng ?? Tôi không muốn. Tôi không có một kịch bản ngắn tiện dụng. Tôi có một kịch bản rất dài, phức tạp mà có lẽ sẽ không có ý nghĩa gì nhiều và thậm chí còn khó hiểu hơn nữa. Tôi có thể làm một phiên bản viết tắt sau tối nay. Tôi nghĩ rằng tôi đã bao gồm các bộ phận có liên quan. Tôi không biết tại chỗ chỉnh sửa có liên quan tại thời điểm đó. Cám ơn. –

Trả lời

12

In ấn "\n" đến một filehandle trên Windows phát ra, theo mặc định, một CARRIAGE RETURN ("\015") tiếp theo là một LINE FEED ("\012") ký tự vì chuỗi tiêu chuẩn mới trên Windows.

Điều này xảy ra một cách minh bạch, vì vậy bạn cần phải ghi đè nó cho filehandle đặc biệt ARGVOUT (xem perldoc perlvar):

#!/usr/bin/perl -i.bak 

use strict; use warnings; 

local ($\, $/); 

while (<>) { 
    binmode ARGVOUT; 
    print; 
} 

Output:

 
C:\Temp> xxd test.txt 
0000000: 7465 7374 0d0a 0d0a      test.... 

C:\Temp> h test.txt 

C:\Temp> xxd test.txt 
0000000: 7465 7374 0a0a       test.. 

Xem thêm perldoc open, perldoc binmodeperldoc perliol (nhờ daotoad).

+5

Nó không thực sự \ n làm bất cứ điều gì. Đó là tập tin dịch \ 012. Tức là, nếu không có văn bản cho một tập tin văn bản, \ n vẫn chỉ là \ 012. –

+0

@brian d foy: Làm rõ thêm. –

+2

Để biết chi tiết cuộc thảo luận về các lớp Perl IO, cơ chế thực hiện bản dịch này, xem perldoc perliol - http://perldoc.perl.org/perliol.html – daotoad

4

binmode(STDOUT) hoạt động không?

+0

+1, vâng, một phần ... xem chỉnh sửa. cám ơn. –

0

Một unix xuống dòng là một nhân vật linefeed, đó là mã ASCII 10.

print "\012";

+1

Trên Windows: 'perl -e 'in qq {\ 012}" | xxd' mang lại '0000000: 0d0a' trừ khi bạn đặt' binmode STDOUT'. –

+1

Nó không phải là một vấn đề với việc có được nhân vật đúng. Đó là bản dịch chế độ văn bản đang sửa đổi đầu ra trong khi ghi vào một tập tin văn bản. –

+0

cảm ơn bạn đã sửa lỗi trên Windows; Tôi đã quên rằng perl "đã giúp" ngay cả khi được nói rõ ràng phải làm gì. –

0

Dữ liệu bạn đang đọc có chứa kết thúc dòng, vì vậy bạn sẽ đưa chúng trở lại.Bạn có thể lột chúng mình với chomp, sau đó thêm kết thúc của riêng bạn trở lại, với điều kiện bạn đã thiết lập binmode như Sinan mô tả ::

while (<>) { 
    binmode; 
    chomp;  # strip off \r\n 
    while (s/search/replace/) { 
     # ... 
    } 
    print; 
    print "\n"; # add your own line ending back 
} 
1

Re: câu hỏi của bạn về binmode bị mất khi $^I mở ra một xử lý đầu ra mới, bạn có thể giải quyết việc này với open pragma:

use open OUT => ':raw'; 

mà sẽ buộc tất cả filehandles mở cho các văn bản để có ': thô' PerlIO lớp (tương đương với binmode không có đối số) để áp dụng cho họ. Chỉ cần cẩn thận nếu bạn đang mở bất kỳ thứ gì khác cho đầu ra mà bạn áp dụng :crlf hoặc bất kỳ lớp nào khác nếu cần.

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