为什么我不能打印很长的字符串?

时间:2014-10-23 18:03:30

标签: string perl

我正在编写一个搜索kml文件的Perl脚本,我需要打印很长的纬度/经度坐标线。以下脚本成功找到我要查找的字符串,但只打印一个空行而不是字符串的值:

#!/usr/bin/perl
# Strips unsupported tags out of a QGIS-generated kml and writes a new one

$file = $ARGV[0];
# read existing kml file
open( INFO, $file );    # Open the file
@lines = <INFO>;        # Read it into an array
close(INFO);            # Close the file
#print @lines;          # Print the array

$x = 0;
$coord_string = "<coordinates>";
# go through each line looking for above string
foreach $line (@lines) {
    $x++;
    if ( $x > 12 ) {

        if ( $line =~ $coord_string ) {
            $thisCooordString = $line;
            $var_startX       = $x;
            print "Found coord string: $thisCoordString\n";
            print "           on line: $var_startX\n";
        }
    }
}

它正在阅读的文件是here 这是我得到的输出:

-bash-4.3$ perl writekml.pl HUC8short.kml

Found coord string:
       on line: 25

Found coord string:
       on line: 38

字符串在Perl中的最大长度是否有上限?该文件中最长的行长约151,000个字符。我已经验证了文件中的所有行都已成功读取。

4 个答案:

答案 0 :(得分:4)

你拼错了变量名(两个 o s vs三个 o ):

$thisCooordString = $line; 
...
print "Found coord string: $thisCoordString\n";

use strictuse warnings添加到您的脚本中以防止出现这类错误。

答案 1 :(得分:2)

始终在每个perl脚本中包含use strictuse warnings

如果您已经这样做了,那么您将收到以下错误消息以提示您进入您的错误:

Global symbol "$thisCoordString" requires explicit package name

添加这些编译指示并简化代码会产生以下结果:

#!/usr/bin/env perl
# Strips unsupported tags out of a QGIS-generated kml and writes a new one

use strict;
use warnings;

local @ARGV = 'HUC8short.kml';

while (<>) {
    if ( $. > 12 && /<coordinates>/ ) {
        print "Found coord string: $_\n";
        print "           on line: $.\n";
    }
}

答案 2 :(得分:1)

您甚至可以尝试使用perl一个衬垫,如下所示:

Windows命令提示符下的Perl One衬垫:

perl -lne "if($_ =~ /<coordinates>/is && $. > 12) { print \"Found coord string : $_ \n"; print \"  on line : $. \n\";}" HUC8short.kml

在unix提示符上的Perl One衬垫:

perl -lne 'if($_ =~ /<coordinates>/is && $. > 12) { print "Found coord string : $_ \n"; print "  on line : $. \n";}' HUC8short.kml

答案 3 :(得分:-2)

正如其他人指出的那样,你需要。不,您 必须 始终使用use strict;use warnings;

如果您使用了strict,则会收到一条错误消息,告知您变量$thisCoordString$thisCooordString未声明为my。使用warnings会警告您,您正在打印未定义的字符串。

您的整个程序都是用一种非常古老(过时)的Perl编程风格编写的。这是我大约二十年前在Perl 3.0天里做过的程序编写类型。从那以后Perl发生了很大的变化,使用更新的语法可以让你更容易阅读和维护程序。

这是您用更现代的语法编写的基本程序:

#! /usr/bin/env perl
#

use strict;             # Lets you know when you misspell variable names
use warnings;           # Warns of issues (using undefined variables
use feature qw(say);    # Let's you use 'say' instead of 'print' (No \n needed)
use autodie;            # Program automatically dies on bad file operations
use IO::File;           # Lots of nice file activity.

# Make Constants constant
use constant {
    COORD_STRING => qr/<coordinates>/, # qr is a regular expression quoted string
};

my $file = shift;

# read existing kml file
open my $fh, '<', $file;  # Three part open with scalar filehandle

while ( my $line = <$fh> ) {
    chomp $line;        # Always "chomp" on read
    next unless $line =~ COORD_STRING; #Skip non-coord lines
    say "Found coord string: $line";
    say "           on line: " . $fh->input_line_number;
}
close $fh;

许多Perl开发人员自学。这没有什么不对,但很多人通过查看其他人的过时代码,或者阅读旧的Perl手册,或者从20世纪90年代从别人那里学习Perl的开发人员来学习Perl。

因此,请在Modern Perl上获取一些书籍并学习新语法。您可能还想了解references之类的内容,这些内容可以让您了解Object Oriented Perl。引用和OO Perl将允许您编写更长和更复杂的程序。