[英]Why does 'chomp' fail to remove newlines on Windows XP with Eclipse and Cygwin Perl?
我正在運行Windows XP,帶有EPIC的Eclipse 3.2和用於我的Perl解釋器的Cygwin,我得到了意想不到的結果。
僅供參考...當我在我的Ubuntu發行版( VMware ,同一台PC)上運行時,我得到了預期的結果。 為什么?
############ CODE: #############
use warnings;
use strict;
my $test = "test";
my $input = <STDIN>;
print length $test, " ", length $input, "\n";
chomp $input;
print "|$test| |$input| \n"; #The bars indicate white space, new line, etc...
print length $test, " ", length $input, "\n";
if ($test eq $input) {
print "TIME TO QUIT";
}
Windows XP上的結果:
test <-- My input
4 6 <-- Lengths printed before chomp
|test| |test <-- Print the variables after chomp
| <-- There is still a new line there
4 5 <-- Lengths after the initial chomp
鑒於Windows XP在問題中的數字,差異必須歸因於CRLF(回車,換行)處理。 chomp
,它看起來是LF而不是CR; 打印將CR轉換為CR LF。
chomp的Perl文檔說如果你為Windows正確設置EOL( $/ = "\\r\\n";
),那么chomp
應該正確地做它的東西:
$/ = "\r\n";
$test = "test\r\n";
print "<<$test>>\n";
chomp $test;
print "<<$test>>\n";
輸出的十六進制轉儲產生:
0x0000: 3C 3C 74 65 73 74 0D 0A 3E 3E 0A 3C 3C 74 65 73 <<test..>>.<<tes
0x0010: 74 3E 3E 0A t>>.
0x0014:
我不確定為什么$/
沒有自動設置 - 可能是Cygwin混淆了事情(假裝太成功它在Unix上運行)。
根據長度,我會說你得到的輸入字符串為:
test<cr><lf>
其中<cr>
和<lf>
分別是ASCII碼0x13和0x10。
當你咀嚼它時,它會移除<lf>
但在那里留下<cr>
。
這幾乎肯定是Eclipse,Cygwin和Windows之間的交互問題,不同意行尾字符序列應該是什么。 我無法用Perl / Cygwin 或 Perl / Windows復制你的問題,但是這個命令給出了類似的結果(在Cygwin中):
echo 'test^M' | perl qq.pl | sed 's/^M/\n/g'
( qq.pl
是你的腳本, "^M"
是實際的CTRL-M)。 這是文本形式的輸出:
4 6
|test| |test
|
4 5
和八進制轉儲:
0000000 2034 0a36 747c 7365 7c74 7c20 6574 7473
4 6 \n | t e s t | | t e s t
064 040 066 012 174 164 145 163 164 174 040 174 164 145 163 164
0000020 7c0a 340a 3520 000a
\n | \n 4 5 \n \0
012 174 012 064 040 065 012 000
0000027
所以我要說你輸入的是<cr>
和 <lf>
,並且打印正在將<cr>
轉換為<lf>
(或者只是為它們做同樣的事情)。
如果您需要針對您的環境的變通方法,可以使用以下命令替換您的chomp
行:
$input =~ s/\r?\n$//;
如:
use warnings;
use strict;
my $test = "test";
my $input = <STDIN>;
print length $test ," ",length $input,"\n";
$input =~ s/\r?\n$//;
print "|$test| |$input|\n";
print length $test," ",length $input,"\n";
if ($test eq $input) {
print "TIME TO QUIT";
}
這對我使用的測試數據在Cygwin上工作(當然,請檢查它自己的情況),但是你可能會發現你可以通過使用所有在行結束序列上達成一致的工具來更好地解決它(例如,Perl for Windows而不是Cygwin可能會為你做這個伎倆)。
以下是如何刪除尾隨\\r\\n
或\\n
(以最后者為准):
$input =~ s@\r?\n\Z(?!\n)@@;
另一種選擇是做一個
binmode(STDIN, ':crlf')
在從STDIN讀取任何內容之前。 這會將尾隨\\r\\n
轉換為\\n
,您可以使用chomp
刪除它。 即使您的輸入僅包含\\n
這也將起作用。 有關更多信息,請參閱有關PerlIO的文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.