获取自动拆分分隔符的值?
Get value of autosplit delimiter?
如果我 运行 一个带有 perl -F
something 的脚本,something 值是否保存在哪里可以找到perl环境的脚本呢?我想编写一个脚本,默认情况下重用输入分隔符(如果它是字符串而不是正则表达式)作为输出分隔符。
查看 source,我认为定界符没有保存在任何地方。当你 运行
perl -F, -an
词法分析器实际生成代码
LINE: while (<>) {our @F=split(q[=11=],[=11=]);
并解析它。此时,有关定界符的任何信息都将丢失。
您最好的选择是手动split
:
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
或将分隔符作为环境变量传递:
export F=,; perl -F$F -ane'print join($ENV{F}, @F)' foo.csv
正如@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[=11=],[=11=]);
然而,这当然是经过编译的,如果您将其 运行 与 B::Deparse 一起使用,您可以看到存储的内容。
$ 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#
您可以改为遍历字节码,因为在到达模式之前每次的开始可能都是相同的。
如果我 运行 一个带有 perl -F
something 的脚本,something 值是否保存在哪里可以找到perl环境的脚本呢?我想编写一个脚本,默认情况下重用输入分隔符(如果它是字符串而不是正则表达式)作为输出分隔符。
查看 source,我认为定界符没有保存在任何地方。当你 运行
perl -F, -an
词法分析器实际生成代码
LINE: while (<>) {our @F=split(q[=11=],[=11=]);
并解析它。此时,有关定界符的任何信息都将丢失。
您最好的选择是手动split
:
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
或将分隔符作为环境变量传递:
export F=,; perl -F$F -ane'print join($ENV{F}, @F)' foo.csv
正如@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[=11=],[=11=]);
然而,这当然是经过编译的,如果您将其 运行 与 B::Deparse 一起使用,您可以看到存储的内容。
$ 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#
您可以改为遍历字节码,因为在到达模式之前每次的开始可能都是相同的。