如何使用"here-doc"将行打印到文件?

Mic*_*Mao 3 perl

基本上这是我在google上编程的结果,最后半小时试图实现一个简单的事情:从中获取用户输入STDIN并将其写入结构化XML文件作为输出,下面是我丑陋的代码:

#!/bin/perl
print "img URL = ?    ";
$img = <>;
chomp($img);
print "filename = ?    ";
$filename = <>;
chomp($filename);

# now write xml with inserted contents to a file:
open (CARDFILE, ">>$filename");
print CARDFILE "<card>\r\n";
print CARDFILE "    <img>$img</img>\r\n";
print CARDFILE "    <type>$type</type>\r\n";
print CARDFILE "    <expansion>$expansion</expansion>\r\n";
print CARDFILE "    <keyword>$keyword</keyword>\r\n";
print CARDFILE "    <color>$color</color>\r\n";
print CARDFILE "    <linkcolor>$linkcolor</linkcolor>\r\n";
print CARDFILE "    <kickercolor>$kickercolor</kickercolor>\r\n";
print CARDFILE "    <cost>$cost</cost>\r\n";
print CARDFILE "    <strength>$strength</strength>\r\n";
print CARDFILE "    <health>$health</health>\r\n";
print CARDFILE "</card>";
close (CARDFILE);  
Run Code Online (Sandbox Code Playgroud)

我是Perl的新手,但我可以告诉我代码中的一些重要问题:

  1. 使用两行先接受STDIN,然后chomp()它摆脱后回车.应该有一个班轮吗?

  2. 我无法弄清楚如何使用"here-doc"的东西一次打印多行文件.没有CARDFILE文件句柄,我可以使用here-doc语法STDOUT在一个print语句中打印所有字符串,现在我必须多次调用print函数.

  3. 对于这些"\r\n"s,有没有办法使用不同的功能,所以我不必记得在每行之后手动插入它们?

amo*_*mon 9

读一条线

阅读单行的习语就是

chomp(my $var = <>);
Run Code Online (Sandbox Code Playgroud)

但我通常最终写一个小子prompt程序:

sub prompt {
  print @_;
  chomp(my $answer = <>);
  return $answer;
}
...;
my $img = prompt("img URL = ? ");
Run Code Online (Sandbox Code Playgroud)

这里,文档

here-doc只是另一种字符串文字,例如

my $str = <<"END";
foo bar
baz
END
print $str;
Run Code Online (Sandbox Code Playgroud)

如果用单引号括起分隔符:<<'END',则无法将变量插入到here-doc中.请注意,结束标记必须始终位于行的开头,但可能包含空格字符:

    my $string = <<'END THIS';
    foo
    bar
END THIS
    # marker must be at start of line!
Run Code Online (Sandbox Code Playgroud)

你可以直接打印here-doc之类的

print CARDFILE <<"END";
<card>
    <img>$img</img>
    <type>$type</type>
    <expansion>$expansion</expansion>
    <keyword>$keyword</keyword>
    <color>$color</color>
    <linkcolor>$linkcolor</linkcolor>
    <kickercolor>$kickercolor</kickercolor>
    <cost>$cost</cost>
    <strength>$strength</strength>
    <health>$health</health>
</card>
END
Run Code Online (Sandbox Code Playgroud)

不同\r\n之处在于,除非使用Windows行结尾保存源文件,否则行末不会出现.但是,here-doc确实包含物理换行符,并且始终以换行符结束.

打印东西

print函数打印由$,特殊变量分隔的参数,然后输出$\变量.默认情况下,这两个都是空的.但我们可以提供一个临时值:

local $\ = "123";
print "foo";
Run Code Online (Sandbox Code Playgroud)

输出:

foo123
Run Code Online (Sandbox Code Playgroud)

当然,我们通常会将其设置为\n.但是有一个捷径:只需在源代码的开头放一个use feature 'say'use 5.010(或更高),然后就可以了

say "foo";
Run Code Online (Sandbox Code Playgroud)

它会自动附加换行符.

打开文件句柄

使用词汇变量.使用三arg打开.做适当的错误处理.这意味着:

use autodie;
open my $fh, "<", "filename";
Run Code Online (Sandbox Code Playgroud)

要么

my $filename = "filename";
open my $fh, "<", $filename or die "Can't open $filename: $!";
Run Code Online (Sandbox Code Playgroud)

第二个参数是模式,它将>>用于追加.明确指定它更安全,而不是文件名的一部分.

一般说明

始终use strict; use warnings;位于脚本的顶部,这有助于发现问题.


Dav*_* W. 7

人们在Perl中听到文件的大问题是他们忘记了行尾的分号.

这里的文件有两种形式.如果在here文档名称周围使用双引号(或无引号),它将插入变量等.

如果在Here Document名称周围使用单引号,则不会进行插值.仔细观察分号和引号的位置.

#! /usr/bin/env perl
#
use warnings;
use strict;
use feature qw(say);

my $foo = "The value of foo";
my $bar = "The value of bar";

my $heredoc =<<"END_HERE_1";
This is my first here document
and this will interpolate things
like $foo and $bar.

Heck, it even shows up correcty
in VIM.
END_HERE_1

say "$heredoc"; #All set

print  <<'END_HERE_2';
This is my first here document
and this will NOT interpolate things
like $foo and $bar.

Heck, it even shows up correcty
in VIM.
END_HERE_2

say "And that's all folks!";
Run Code Online (Sandbox Code Playgroud)