获取自动拆分分隔符的值?

Posted

技术标签:

【中文标题】获取自动拆分分隔符的值?【英文标题】:Get value of autosplit delimiter? 【发布时间】:2016-06-10 06:07:23 【问题描述】:

如果我使用perl -Fsomething 运行脚本,该 something 值是否保存在脚本可以找到的 Perl 环境中的任何位置?我想编写一个脚本,默认情况下重用输入分隔符(如果它是字符串而不是正则表达式)作为输出分隔符。

【问题讨论】:

【参考方案1】:

看着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

或将分隔符作为参数传递给您的脚本:

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

或将分隔符作为环境变量传递:

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

【讨论】:

这就是我害怕的。谢谢。 顺便说一句,perl -F, -an 在技术上是多余的; -F 本身意味着-a-n(您可以通过手动指定-p 来覆盖)。包含它们可能更清楚,尽管当您编写单行而不是要保存的脚本时,清晰度通常不是优先事项。 :)【参考方案2】:

正如@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);

不过,这当然是经过编译的,如果您使用 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#

您可以改为遍历字节码,因为在您到达模式之前,每次开始可能都是相同的。

【讨论】:

嗯,这令人印象深刻,但对我的应用程序来说有点矫枉过正。我只会做非自动拆分。

以上是关于获取自动拆分分隔符的值?的主要内容,如果未能解决你的问题,请参考以下文章

Redshift - 拆分列以查找位置不确定的分隔符之间的值

如何将逗号分隔的值拆分为列

拆分字符串并在不同分隔符之前获取值

获取字符串,按分隔符拆分并插入到 Oracle 中的表过程 [重复]

获取拆分字符串数组的最后一个元素

Arduino 拆分字符 * 基于分隔符到值