2009-11-30 8 views
11

Domyślnie perl drukuje \ r \ nw środowisku win32. Jak mogę to zmienić? Używam perla, aby dokonać pewnych zmian w kodzie źródłowym w repozytorium i nie chcę zmieniać wszystkich znaków nowej linii.Jak mogę wydrukować pojedynczy znak nowej linii w Perlu na Win32?

Próbowałem zmienić separator rekordów wyjściowych, ale bez powodzenia.

Dzięki!

Edit: chcielibyście zawierać przykładowy kod - Robię wyszukiwania i zamiany na kilka plików, które następują stosunkowo prosty wzór takiego:

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

use strict; 
use warnings; 

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

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

    } 
    print; 
} 

ten powinien zastąpić wszystkie wystąpienia „cześć "with" world "dla wszystkich plików przekazywanych na linii cmd.

Edit 2: Próbowałem binmode jak sugeruje bez powodzenia początkowo. Zrobiłem jeszcze więcej i odkryłem, że $^I (zmienna specjalna w miejscu edycji) nadpisuje numer binmode. Jakieś prace, aby nadal móc korzystać z edycji w witrynie?

Edit 3: W Sinan zaznacza poniżej, musiałem użyć binmode ARGVOUT z $^I zamiast binmode STDOUT w moim przykładzie. Dzięki.

+2

Jeśli zmieniłeś separator rekordów wyjściowych, to była jedyna rzecz, którą możesz zrobić. Zgaduję, że popełniłeś inny błąd (np. Nie podzieliłeś poprawnie linii wejściowych lub nie udawałeś ich). –

+0

Czy możesz podać przykład kodu, który wypisuje '\ r \ n', kiedy go nie chcesz? – Ether

+0

@Sanan, dlaczego założyć, że jestem niechętny? Nie jestem niechętny. Nie mam pod ręką krótkiego scenariusza. Mam bardzo długi, skomplikowany skrypt, który prawdopodobnie nie będzie miał większego sensu i będzie jeszcze bardziej zagmatwany. Dziś wieczorem mogę zrobić skróconą wersję. Myślałem, że włączam odpowiednie części. Nie wiedziałem, że edycja na miejscu była istotna w tym czasie. Dzięki. –

Odpowiedz

12

Druk "\n" do uchwytu pliku w systemie Windows emituje przez Domyślnie CARRIAGE RETURN ("\015"), a następnie przez LINE FEED ("\012") ponieważ jest to standardowa sekwencja nowej linii w systemie Windows.

Dzieje się tak przejrzysty, więc trzeba zastąpić go do specjalnego uchwytu pliku ARGVOUT (patrz perldoc perlvar):

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

use strict; use warnings; 

local ($\, $/); 

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

wyjściowa:

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

Zobacz również perldoc open, perldoc binmode i perldoc perliol (dzięki daotoad).

+5

To nie jest \ n robienie niczego. To jest tłumaczenie pliku \ 012. Oznacza to, że bez zapisu do pliku tekstowego, \ n nadal jest \ 012. –

+0

@brian d foy: dodano wyjaśnienie. –

+2

Szczegółowe omówienie warstw Perl IO, mechanizmu, który wykonuje to tłumaczenie, patrz perldoc perliol - http://perldoc.perl.org/perliol.html – daotoad

4

Czy działa binmode(STDOUT)?

+0

+1, tak, częściowo ... zobacz edytuj. dzięki. –

0

uniksowy nowej linii jest znakiem końca wiersza, który jest kodem ASCII 10.

print "\012";

+1

W systemie Windows: 'perl -e" print qq {\ 012} "| xxd' daje '0000000: 0d0a', chyba że ustawisz' binmode STDOUT'. –

+1

To nie jest problem z uzyskaniem odpowiedniej postaci. Jest to tłumaczenie w trybie tekstowym, które modyfikuje wynik podczas zapisywania do pliku tekstowego. –

+0

dziękuję za poprawienie mnie w Windows; Zapomniałem, że perl "pomógł", nawet gdy wyraźnie powiedziano, co robić. –

0

Dane, które czytasz, zawierają zakończenia linii, więc odzyskujesz je ponownie.Można je rozebrać się z chomp, następnie dodać własne zakończenie powrotem, o ile masz ustawione BINMODE jak opisuje Sinan ::

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

Re: zapytanie o BINMODE giną podczas $^I otwiera nowy uchwyt wyjściowego, można rozwiązać ten problem z open pragma:

use open OUT => ':raw'; 

który zmusi wszystkich uchwytów plików otwarty do pisania mieć „”: surowy warstwę perlio (odpowiednik binmode bez argumentów), aby zastosować się do nich. Po prostu zachowaj ostrożność, jeśli otwierasz coś, co jest inne niż dla wyniku, który zastosujesz :crlf lub dowolną inną warstwę w razie potrzeby.

Powiązane problemy