全局符号“ $ fh”需要显式的程序包名称(您是否忘了声明“ my $ fh”?)

时间:2018-08-10 17:13:15

标签: perl

  1. 我将扩展名为.srt,.ass,.ssa,.txt的文件(非递归)放在以下文件中:

    my @subfiles = glob '*.srt *.txt *.ass *.ssa';
    
  2. 然后,为我调用的spumux编写xml子文件: WRITESUBXML();如下:

    sub WRITESUBXML {
        foreach my $i (@subfiles) {
            $SUBXMl="/users/dragonzero29/.wine/drive_c/mvtmp/$subfiles[$i].xml";
            open(my $fh, '>', $SUBXMl) or die "Could not open file $SUBXMl $!";
            print $fh "<subpictures format=\"NTSC\">\n";
            print $fh "<stream>\n";
            print $fh "<textsub filename=\"$subfiles[$i]\"\n";
            print $fh "characterset=\"UTF-8\"\n";
            print $fh "fontsize=\"28.0\"\n";
            print $fh "font=\"/users/dragonzero29/.wine/drive_c/mvtmp/arial.ttf\"\n";
            print $fh "fill-color=\"yellow\"\n";
            print $fh "outline-color=\"LightGray\"\n";
            print $fh "outline-thickness=\"2.0\"\n";
            print $fh "horizontal-alignment=\"center\"\n";
            print $fh "vertical-alignment=\"bottom\"\n";
            print $fh "left-margin=\"60\"\n";
            print $fh "right-margin=\"60\"\n";
            print $fh "top-margin=\"20\"\n";
            print $fh "bottom-margin=\"30\"\n";
            print $fh "subtitle-fps=\"29.97\"\n";
            print $fh "movie-fps=\"29.97\"\n"; 
            print $fh "movie-width=\"720\"\n";
            print $fh "movie-height=\"480\"\n";
            print $fh "force=\"no\"/>\n";
            print $fh "</stream>\n";
            print $fh "</subpictures>";
            close($fh);
        }
    }
    
  3. 然后,稍后我调用该函数以写入最终的dvdauthor文件 WRITEAUTHORXML();,其中包含:

    sub WRITEAUTHORXML {
        $AUTHORFILe="/users/dragonzero29/.wine/drive_c/mvtmp/authormovie.xml";
        open(my $fh, '>', $AUTHORFILe) or die "Could not open file $AUTHORFILe $!";
        print $fh "<dvdauthor dest=\"/users/dragonzero29/.wine/drive_c/mvtmp/DVD\">\n";
        print $fh "<vmgm />\n";
        print $fh "<titleset>\n";
        print $fh "<menus>\n";
        print $fh "<pgc>\n";
        print $fh "<button> jump title 1\; </button>\n";
        print $fh "<vob file=\"/users/dragonzero29/.wine/drive_c/mvtmp/menu.mpg\" pause=\"inf\"/>\n";
        print $fh "</pgc>\n";
        print $fh "</menus>\n";
        print $fh "<titles>\n";
        foreach my $LANg = grep(/^EN/ || /^ES/,@subfiles) {
            print $fh "<subpicture lang=\"$LANg\"\n";
        }
        print $fh "<pgc>\n";
        print $fh "<vob file=\"/users/dragonzero29/.wine/drive_c/mvtmp/$MOVIe.MUXED.MPG\" 
        print $fh "<post>\n";
        print $fh "call menu\;\n";
        print $fh "</post>\n";
        print $fh "</pgc>\n";
        print $fh "</titles>\n";
        print $fh "</titleset>\n";
        print $fh "</dvdauthor>\n";
        close($fh);
        return 0;
    }
    

运行时会吐出:

syntax error at /users/dragonzero29/cm2dvd_v2.pl line 309, near "$LANg ="
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 312.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 313.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 314.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 315.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 316.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 317.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 318.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 319.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 320.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 321.
syntax error at /users/dragonzero29/cm2dvd_v2.pl line 323, near "}"
/users/dragonzero29/cm2dvd_v2.pl has too many errors.

好吧,编辑使我成功地编译了脚本,并且dvd项目脚本一直可以进行iso创建,但是我注意到甚至没有创建字幕xml文件,因此最终的dvd没有字幕... aargh :(请帮助。这也是用于生成xml文件的代码,与上面的代码一起使用

foreach my $i(0 .. $#subxmlfiles) {
system("spumux -s0 -m dvd -P 
\"/users/dragonzero29/.wine/drive_c/mvtmp/$subxmlfiles[$i]\" < 
\"/users/dragonzero29/.wine/drive_c/mvtmp/$MOVIe.MUXED.MPG\" > 
\"/users/dragonzero29/.wine/drive_c/mvtmp/$MOVIe.MUXED.MPG\"\n\n");
}

对不起,我仍然不明白如何从TextMate放置代码 请告知这个空间。

2 个答案:

答案 0 :(得分:3)

如果存在语法错误,请忽略所有其他错误并首先处理该语法错误。

语法错误通常会使perl混淆您所处的范围;在这里,它无法解析错误的foreach my $LANg,但确实看到了}并认为它结束了子。因此,其后的所有内容都没有词汇$fh

答案 1 :(得分:2)

这部分在语法上不正确:

foreach my $LANg = grep(/^EN/ || /^ES/,@subfiles) {
print $fh "<subpicture lang=\"$LANg\"\n";
}

您至少需要将其重写为:

foreach my $LANg (grep(/^EN/ || /^ES/,@subfiles)) {
    print $fh "<subpicture lang=\"$LANg\"\n";
}

但我建议改为:

foreach my $lang (grep { /^(?:EN|ES)/ } @subfiles) {
    print $fh "<subpicture lang=\"$lang\"\n";
}

请注意,如果@subfiles是文件名列表,则grep可能不会按照您的期望执行逻辑操作,grep将返回以ENES开头的文件名(是它们是这样命名的吗?您需要考虑路径中是否包含目录),然后返回整个文件名(不只是匹配的文件名)在$lang中。因此,$lang绝不会只是ENES而是整个文件名。如果您只需要提取名称的一部分,可以照看map,它通常是grep的好伴侣。

正如@Borodin在注释中指出的那样,您在代码中还有其他各种问题,例如$i中的foreach my $i (@subfiles)变量不是索引(0、1、2等),而是您要使用@subfiles迭代到foreach的一个元素,即文件名,因此$subnames[$i]将是运行时错误,因为$i不是索引(数字值)。

因此,请确保在脚本之上添加use strict; use warnings;并调试语法,然后调试运行时错误。

您还可以进行许多其他常规改进。 例如,在https://perldoc.perl.org/perlop.html#Quote-Like-Operators中搜索“ <<EOF”,看看“ here-documents”。

这将允许您替换例如:

print $fh "<vmgm />\n";
print $fh "<titleset>\n";
print $fh "<menus>\n";
print $fh "<pgc>\n";

通过:

print $fh <<'EOF';
<vmgm />
<titleset>
<menus>
<pgc>
EOF

这将大大简化代码,因为您无需在其中转义"

更多想法:

  • 不要命名变量$i甚至$LANg:第一个变量没有任何语义值,第二个变量应为$lang,因为混合大小写容易出错
  • 以相同的方式,将您的函数命名为小写字母,并将文件名作为参数传递,而不是在函数内部进行硬编码,以便它们可以轻松地与其他路径一起使用
  • 像这样逐行打印XML容易出错。例如,您是否知道需要转义&<>,否则XML无效?使用图书馆为您做到这一点。
  • 照顾模板,例如Template Toolkit库;这样可以将代码与文本(XML模板)分开,这样做有很多好处(包括自动转义上述问题)。