Se eseguo uno script con perl -F
qualcosa di, è quello qualcosa di valore salvato in un ambiente Perl dove lo script può trovarlo? Mi piacerebbe scrivere uno script che riutilizza di default il delimitatore di input (se si tratta di una stringa e non di un'espressione regolare) come delimitatore di output.Ottieni il valore del delimitatore autosplit?
risposta
Guardando allo source, non penso che il delimitatore sia stato salvato da nessuna parte. Quando si esegue
perl -F, -an
il lexer in realtà genera il codice
LINE: while (<>) {our @F=split(q\0,\0);
e lo analizza. A questo punto, qualsiasi informazione sul delimitatore viene persa.
La soluzione migliore è quella di split
a mano:
perl -ne'BEGIN { $F="," } @F=split(/$F/); print join($F, @F)' foo.csv
o per passare il delimitatore come argomento per lo script:
F=,; perl -F$F -sane'print join($F, @F)' -- -F=$F foo.csv
o per passare il delimitatore come ambiente variabile:
export F=,; perl -F$F -ane'print join($ENV{F}, @F)' foo.csv
Come @ThisSuitIsBlackNot dice che sembra che il delimitatore sia stato salvato ovunque.
questo è come il perl.c memorizza il parametro -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;
e poi il lexer genera il codice
LINE: while (<>) {our @F=split(q\0,\0);
tuttavia questo è ovviamente compilato, e se lo si esegue con B :: Sparse puoi vedere cosa viene memorizzato.
$ perl -MO=Deparse -F/e/ -e ''
LINE: while (defined($_ = <ARGV>)) {
our(@F) = split(/e/, $_, 0);
}
-e syntax OK
Essere perl c'è sempre un modo, per quanto brutto. (E questo è parte del codice più brutto che ho scritto in un po '):
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";
}
uscita:
$ perl -Fe/\\\(\\[\\\<\\{\"e testy.pl
m#e/\(\[\<\{"e#
Si potrebbe possibile attraversare il bytecode, invece, fin dall'inizio, probabilmente sarà identico ogni volta fino a raggiungere il modello.
Beh, è impressionante, ma un po 'eccessivo per la mia applicazione. Farò solo la divisione non automatica. –
Questo è quello che temevo. Grazie. –
BTW, 'perl -F, -an' è tecnicamente ridondante; '-F' di per sé implica sia' -a' che '-n' (che puoi sovrascrivere specificando manualmente' -p'). Probabilmente è più chiaro includerli, sebbene la chiarezza non sia in genere una priorità quando si scrive un one-liner anziché uno script da salvare. :) –