2014-06-16 8 views
7

Unter Linux läuft dies wie erwartet:Schaltet das awk CR LF-Handling bei Cygwin aus?

$ echo -e "line1\r\nline2"|awk -v RS="\r\n" '/^line/ {print "awk: "$0}' 
awk: line1 
awk: line2 

Aber unter Windows die \ r fallen gelassen wird (awk hält diese eine Zeile):

Fenster:

$ echo -e "line1\r\nline2"|awk -v RS="\r\n" '/^line/ {print "awk: "$0}' 
awk: line1 
line2 

Windows-GNU Awk 4.0 .1 Linux GNU Awk 3.1.8

EDIT von @EdMorton (sorry, wenn das eine unerwünschte Ergänzung ist, aber ich denke, vielleicht hilft es dem onstrate der Ausgabe):

Betrachten Sie diese RS Einstellung und Eingabe (auf Cygwin):

$ awk 'BEGIN{printf "\"%s\"\n", RS}' | cat -v 
" 
" 
$ echo -e "line1\r\nline2" | cat -v 
line1^M 
line2 

Dies ist Solaris mit gawk:

$ echo -e "line1\r\nline2" | awk '1' | cat -v 
line1^M 
line2 

und das ist Cygwin mit gawk:

$ echo -e "line1\r\nline2" | awk '1' | cat -v 
line1 
line2 

RS war nur die Standard-Zeilenumbruch, also wo ging die Kontrolle-M in Cygwin?

+1

Ja, das habe ich auch in Cygwin gesehen. Ich konnte nicht gestört werden, es zu untersuchen oder zu debuggen, und ich habe sehr wenige Dateien, die '' s in ihnen haben, also habe ich bei Bedarf einfach ein 'tr-d '\ r' | awk ... 'davor, um die' \ r's zu löschen. Hoffentlich wird jemand etwas Licht abwerfen - gute Frage! –

+0

Haben Sie versucht "-V IRS"? Hinweis I für Eingabe – mlt

+1

'awk -v IRS = etwas? Das würde eine unbenutzte, benutzerdefinierte awk-Variable namens 'IRS' auf' etwas' setzen. Dies hätte keine Auswirkungen auf dieses Problem. –

Antwort

4

ich gerade mit Arnold Robbins (der Anbieter von gawk) überprüft, und die Antwort ist, dass es durch die C-Bibliotheken etwas getan hat und es zu stoppen passiert Sie die awk binmode Variable auf 3 gesetzt ist:

$ echo -e "line1\r\nline2" | awk '1' | cat -v 
line1 
line2 

$ echo -e "line1\r\nline2" | awk -v BINMODE=3 '1' | cat -v 
line1^M 
line2 

Weitere Informationen finden Sie auf der Manpage, wenn Sie interessiert sind.

+0

Die Verwendung von BINMODE funktioniert auch unter Linux, obwohl ich nicht davon ausgehen möchte, dass dies der Grund für all dies ist. Vielleicht kann Arnold eine Lösung vorschlagen (dies ist vielleicht ein Standard für Windows). – jcalfee314

+0

Ich denke, das ist ein Problem für mehr als gawk, und gawk arbeiten würde wahrscheinlich bestehende Skripte zu brechen und/oder Konflikte mit anderen Funktionen/Tools usw., so dass ich Arnold nicht einmal bitten, um diese zu betrachten. Ich bin nur glücklich, etwas zu haben, das funktioniert! –

4

Es scheint, als wäre das Problem awk spezifisch unter Cygwin.
Ich habe ein paar verschiedene Dinge ausprobiert und es scheint, dass awk stillschweigend behandelt, \r\n durch \n in den Eingabedaten zu ersetzen.

Wenn wir einfach awk fragen Sie den Text unmodifizierten zu wiederholen, wird es „sanieren“, um den Wagenrücklauf, ohne zu fragen:

$ echo -e "line1\r\nline2" | od -a 
0000000 l i n e 1 cr nl l i n e 2 nl 
0000015 

$ echo -e "line1\r\nline2" | awk '{ print $0; }' | od -a 
0000000 l i n e 1 nl l i n e 2 nl 
0000014 

Es wird jedoch verlassen, um andere Zeilenumbrüche intakt:

$ echo -e "Test\rTesting\r\nTester\rTested" | awk '{ print $0; }' | od -a 
0000000 T e s t cr T e s t i n g nl T e s 
0000020 t e r cr T e s t e d nl 
0000033 

Die Verwendung eines benutzerdefinierten Datensatzseparators von _ endete und ließ den Wagen intakt zurück:

$ echo -e "Testing\r_Tested" | awk -v RS="_" '{ print $0; }' | od -a 
0000000 T e s t i n g cr nl T e s t e d nl 
0000020 nl 
0000021 

Das deutlichste Beispiel beinhaltet \r\n in den Daten zu haben, aber nicht als voneinander zu trennen sind:

$ echo -e "Testing\r\nTested_Hello_World" | awk -v RS="_" '{ print $0; }' | od -a 
0000000 T e s t i n g nl T e s t e d nl H 
0000020 e l l o nl W o r l d nl nl 
0000034 

awk blind \r\n-\n in den Eingangsdaten konvertieren wird, obwohl wir fragen, hat es nicht zu tun.

Diese Substitution scheint vor der Anwendung der Datensatztrennung zu geschehen, was erklärt, warum RS="\r\n" niemals mit irgendetwas übereinstimmt. Zu der Zeit awk ist auf der Suche nach \r\n, es ist bereits durch \n in den Eingabedaten ersetzt.

+0

+1; großes Detektiv. [MSYS] (http://www.mingw.org/wiki/MSYS) zeigt das gleiche Verhalten. "sed" zeigt dieses Verhalten auch auf mindestens MSYS, vermutlich auch auf Cygwin; Versuchen Sie 'sed '' <<< $ 'line1 \ r \ nline2' | od -a'. – mklement0

+0

Ist das nicht das, womit wir angefangen haben und nach "warum" und "wie hören wir damit auf?" ??? –