2016-02-26 30 views
5

如果我使用perl -F運行一個腳本,是的東西值保存在腳本可以找到它的Perl環境中的任何地方?我想編寫一個腳本,默認情況下,將輸入分隔符(如果它是一個字符串而不是正則表達式)重用爲輸出分隔符。獲取autosplit分隔符的值?

回答

4

看着source,我不認爲分隔符保存在任何地方。當您運行

perl -F, -an 

詞法分析器實際生成的代碼

LINE: while (<>) {our @F=split(q\0,\0); 

,並對其進行解析。此時,關於分隔符的任何信息都將丟失。


你最好的選擇是split手:

perl -ne'BEGIN { $F="," } @F=split(/$F/); print join($F, @F)' foo.csv 

或分隔符作爲參數傳遞給你的腳本:

​​

或分隔符傳遞作爲環境變量:

export F=,; perl -F$F -ane'print join($ENV{F}, @F)' foo.csv 
+0

這就是我所害怕的。謝謝。 –

+1

順便說一下,'perl -F,-an'在技術上是多餘的; '-F'本身意味着'-a'和'-n'(你可以通過手動指定'-p'來覆蓋)。可能更清楚地包括它們,儘管當你寫一行代碼而不是要保存的腳本時,清晰度通常不是優先事項。 :) –

0

由於@ThisSuitIsBlackNot說它看起來像分隔符保存在任何地方。

這是怎麼perl.c存儲-F參數

case 'F': 
PL_minus_a = TRUE; 
PL_minus_F = TRUE; 
    PL_minus_n = TRUE; 
PL_splitstr = ++s; 
while (*s && !isSPACE(*s)) ++s; 
PL_splitstr = savepvn(PL_splitstr, s - PL_splitstr); 
return s; 

然後詞法分析器生成的代碼

LINE: while (<>) {our @F=split(q\0,\0); 

但是這當然是編的,如果你去運行它::貶低你可以看到存儲的內容。

$ perl -MO=Deparse -F/e/ -e '' 
LINE: while (defined($_ = <ARGV>)) { 
    our(@F) = split(/e/, $_, 0); 
} 
-e syntax OK 

作爲perl,總是有一種方式,但是很醜。 (這是一些我寫的,而最醜陋的代碼):

use B::Deparse; 
use Capture::Tiny qw/capture_stdout/; 
BEGIN { 
    my $f_var; 
} 

unless ($f_var) { 
    $stdout = capture_stdout { 
     my $sub = B::Deparse::compile(); 
     &{$sub}; # Have to capture stdout, since I won't bother to setup compile to return the text, instead of printing 
    }; 

    my (undef, $split_line, undef) = split(/\n/, $stdout, 3); 
    ($f_var) = $split_line =~ /our\(\@F\) = split\((.*)\, \$\_\, 0\);/; 
    print $f_var,"\n"; 
} 

輸出:

$ perl -Fe/\\\(\\[\\\<\\{\"e testy.pl 
m#e/\(\[\<\{"e# 

你可以可以遍歷字節碼代替,因爲一開始可能每次都將是相同的直到你達到模式。

+0

那麼,這是令人印象深刻的,但對我的應用程序有點過度。我只是做非自動分裂。 –