2016-02-26 12 views
5

यदि मैं perl -Fकुछ के साथ एक स्क्रिप्ट चलाता हूं, तो कुछ मूल्य पर्ल पर्यावरण में कहीं भी सहेजा गया है जहां स्क्रिप्ट इसे पा सकती है? मैं एक स्क्रिप्ट लिखना चाहता हूं कि डिफ़ॉल्ट रूप से आउटपुट डिलीमीटर के रूप में इनपुट डिलीमीटर (यदि यह एक स्ट्रिंग है और नियमित अभिव्यक्ति नहीं है) का पुन: उपयोग करता है।ऑटोस्प्लिट डेलीमीटर का मूल्य प्राप्त करें?

उत्तर

4

source पर देखकर, मुझे नहीं लगता कि डेलीमीटर कहीं भी बचाया जाता है। जब आप

perl -F, -an 

चलाने lexer वास्तव में कोड

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

उत्पन्न करता है और यह पार्स करता है। इस बिंदु पर, डेलीमीटर के बारे में कोई जानकारी खो जाती है।

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

या अपनी स्क्रिप्ट के लिए एक तर्क के रूप सीमांकक पारित करने के लिए:

F=,; perl -F$F -sane'print join($F, @F)' -- -F=$F foo.csv 

या एक वातावरण के रूप में पारित करने के लिए सीमांकक


आपका सबसे अच्छा विकल्प हाथ से split है परिवर्तनीय:

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

यही वह था जिसे मैं डरता था। धन्यवाद। –

+1

बीटीडब्ल्यू, 'perl -F, -an' तकनीकी रूप से अनावश्यक है; '-F' स्वयं ही '-a' और' -n' दोनों का तात्पर्य है (जिसे आप मैन्युअल रूप से' -p' निर्दिष्ट करके ओवरराइड कर सकते हैं)। शायद उन्हें शामिल करने के लिए स्पष्ट, हालांकि स्पष्टता आमतौर पर प्राथमिकता नहीं होती है जब आप सहेजी जाने के लिए एक स्क्रिप्ट के बजाय एक-लाइनर लिख रहे हैं। :) –

0

@ThisSuitIsBlackNot के रूप में ऐसा लगता है कि ऐसा लगता है कि delimiter कहीं भी बचाया गया है।

यह कैसे 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; 

और फिर lexer कोड

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 

होने के नाते हमेशा एक तरीका है, हालांकि बदसूरत है। (और यह ugliest कोड मैं एक समय में एक में लिखा है में से कुछ है):

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

अच्छा, यह प्रभावशाली है, लेकिन मेरे आवेदन के लिए थोड़ा अधिक है। मैं सिर्फ गैर-ऑटो विभाजन करूँगा। –

संबंधित मुद्दे