2009-11-30 4 views
11

Standardmäßig druckt Perl \ r \ n in einer Win32-Umgebung. Wie kann ich dies überschreiben? Ich verwende Perl, um einige Änderungen an Quellcode in einem Repository vorzunehmen, und ich möchte nicht alle Zeilenumbruchzeichen ändern.Wie kann ich nur einen Unix-Newline in Perl auf Win32 drucken?

Ich habe versucht, die Ausgabe Rekord Trennzeichen, aber ohne Glück.

Danke!

Edit: Wollte ein Codebeispiel enthalten - ich bin der Suche und einige Dateien ersetzen über die eine relativ einfache Muster wie diese folgen:

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

use strict; 
use warnings; 

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

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

    } 
    print; 
} 

Diese jede Instanzen ersetzen sollte „hallo "with" world "für alle Dateien, die über die cmd-Zeile übergeben wurden.

Edit 2: Ich versuchte, die binmode als ohne Erfolg vorgeschlagen zunächst. Ich vertiefte mich ein wenig mehr und fand, dass $^I (die Inplace-Edit-Spezialvariable) überschrieb binmode. Irgendwelche Arbeiten um den Inplace Edit noch nutzen zu können?

bearbeiten 3: Wie Sinan unten weist darauf hin, brauchte ich binmode ARGVOUT mit $^I statt binmode STDOUT in meinem Beispiel zu verwenden. Vielen Dank.

+2

Wenn Sie das Ausgabesatztrennzeichen geändert haben, war dies das einzige, was Sie tun können. Ich nehme an, Sie haben einen anderen Fehler gemacht (zum Beispiel, die eingehenden Zeilen nicht richtig zu teilen oder sie nicht zu zerhacken). –

+0

Können Sie ein Beispiel für einen Code geben, der '\ r \ n' druckt, wenn Sie es nicht möchten? – Ether

+0

@Sinan, warum würdest du annehmen, dass ich nicht will ?? Ich bin nicht unwillig. Ich habe kein kurzes Skript zur Hand. Ich habe ein sehr langes, kompliziertes Skript, das wahrscheinlich nicht viel Sinn ergibt und noch verwirrender wäre. Ich kann heute Abend eine verkürzte Version machen. Ich dachte, ich würde die relevanten Teile einbeziehen. Ich wusste nicht, dass die In-situ-Bearbeitung zu der Zeit relevant war. Danke. –

Antwort

12

Printing "\n" zu einem Dateihandle auf Windows aussendet, standardmäßig eine CARRIAGE RETURN ("\015"), gefolgt von einem LINE FEED ("\012") Zeichen, weil das die Standard-Newline-Sequenz unter Windows ist.

Diese transparent geschieht, so dass Sie es für die spezielle Dateihandle ARGVOUT (siehe perldoc perlvar) außer Kraft setzen müssen:

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

use strict; use warnings; 

local ($\, $/); 

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

Ausgang: auch

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

See perldoc open, perldoc binmode und perldoc perliol (dank daotoad).

+5

Es ist nicht wirklich das \ n etwas zu tun. Es ist die Dateihandle übersetzen \ 012. Das heißt, ohne in ein Textdateihandle zu schreiben, ist \ n immer noch \ 012. –

+0

@brian d foy: Erläuterung hinzugefügt. –

+2

Für eine detaillierte Diskussion der Perl IO-Schichten, der Mechanismus, der diese Übersetzung tut, siehe perldoc perliol - http://perldoc.perl.org/perliol.html – daotoad

4

Funktioniert binmode(STDOUT)?

+0

+1, ja, teilweise ... siehe bearbeiten. Danke. –

0

Ein Unix newline ist ein Zeilenvorschub-Zeichen, das 10. ASCII-Code ist

print "\012";

+1

Unter Windows: 'perl -e" print qq {\ 012} "| xxd' ergibt '0000000: 0d0a', es sei denn, Sie setzen' binmode STDOUT'. –

+1

Es ist kein Problem, den richtigen Charakter zu bekommen. Es ist die Textmodus-Übersetzung, die die Ausgabe beim Schreiben in ein Textdateihandle verändert. –

+0

danke für die Korrektur mich auf Windows; Ich hatte vergessen, dass Perl "geholfen" hat, auch wenn explizit gesagt wurde, was zu tun ist. –

0

Die Daten, die Sie einlesen, enthalten Zeilenenden, Sie erhalten sie also wieder zurück.Sie können sie sich mit chomp abzustreifen, dann ist dein eigenes Ende wieder hinzufügen, sofern Sie binmode gesetzt haben, wie Sinan beschreibt ::

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

Re: Ihre Frage über die binmode verloren gehen, wenn $^I einen neuen Ausgabe Griff öffnet, Sie können dies mit dem open Pragma lösen:

use open OUT => ':raw'; 

die alle Handles geöffnet zum Schreiben zwingen wird, die haben ‚: raw‘ PerlIO Schicht (entspricht binmode ohne Argument) auf sie anzuwenden. Passen Sie nur auf, wenn Sie etwas öffnen sonst für die Ausgabe, die Sie anwenden :crlf oder eine andere Schicht nach Bedarf.

Verwandte Themen