首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用"here-doc“将行打印到文件中?

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

Stack Overflow用户
提问于 2013-07-04 23:50:20
回答 3查看 19.6K关注 0票数 8

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

代码语言:javascript
复制
#!/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);  

我对Perl并不熟悉,但我可以告诉您我的代码中的一些重要问题:

  1. 首先使用两行来接收STDIN,然后再使用chomp() it来消除尾部的回车。应该有一条单线吗?

  1. 我不知道如何使用“这里-文档”的东西打印多行文件在一次。没有CARDFILE文件句柄,我可以在一个print语句中使用here-doc语法将所有字符串打印到STDOUT。现在我必须多次调用打印函数。

  1. 对于这些"\r\n",是否有一种方法可以使用不同的函数,这样我就不必记得在每一行之后手动插入它们了吗?
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-05 00:18:42

读一行

读一行的成语是

代码语言:javascript
复制
chomp(my $var = <>);

但是我通常会编写一个小的prompt子例程:

代码语言:javascript
复制
sub prompt {
  print @_;
  chomp(my $answer = <>);
  return $answer;
}
...;
my $img = prompt("img URL = ? ");

这里-医生

这里的-doc只是另一种字符串文字。

代码语言:javascript
复制
my $str = <<"END";
foo bar
baz
END
print $str;

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

代码语言:javascript
复制
    my $string = <<'END THIS';
    foo
    bar
END THIS
    # marker must be at start of line!

您可以直接打印这里的-doc,如

代码语言:javascript
复制
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

不同之处在于,除了保存带有Windows结尾的源文件外,行尾将不存在\r\n。但是,here-doc确实包含物理换行符,并且总是以换行符结束。

印刷物

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

代码语言:javascript
复制
local $\ = "123";
print "foo";

输出:

代码语言:javascript
复制
foo123

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

代码语言:javascript
复制
say "foo";

它会自动追加换行符。

打开文件句柄

使用词法变量。用三支枪打开。做正确的错误处理。这意味着:

代码语言:javascript
复制
use autodie;
open my $fh, "<", "filename";

代码语言:javascript
复制
my $filename = "filename";
open my $fh, "<", $filename or die "Can't open $filename: $!";

第二个参数是模式,它将是用于附加的>>。更安全的做法是显式地指定它,而不是作为文件名的一部分。

一般注记

始终将use strict; use warnings;放在脚本的顶部,这有助于发现问题。

票数 11
EN

Stack Overflow用户

发布于 2013-07-05 00:19:28

如果您想要这里的文档,您可以使用:

代码语言:javascript
复制
#!/usr/bin/env perl
use strict;
use warnings;

print "img URL = ?    ";
chomp(my $img = <>);
print "filename = ?   ";
chomp(my $filename = <>);

# now write xml with inserted contents to a file:
open my $CARDFILE, ">>", $filename or die "Failed to open file $filename for writing";
my $type = "unregimented";
my $expansion = "contracted";
my $keyword = "lock";
my $color = "green";
my $linkcolor = "blue";
my $kickercolor = "red";
my $cost = '$0.00';
my $strength = "humungous";
my $health = "excellent";

print $CARDFILE <<EOF;
<card>\r
    <img>$img</img>\r
    <type>$type</type>\r
    <expansion>$expansion</expansion>\r
    <keyword>$keyword</keyword>\r
    <color>$color</color>\r
    <linkcolor>$linkcolor</linkcolor>\r
    <kickercolor>$kickercolor</kickercolor>\r
    <cost>$cost</cost>\r
    <strength>$strength</strength>\r
    <health>$health</health>\r
</card>\r
EOF

close $CARDFILE;

注意压缩后的输入,数据现在垂直排列--尽管已经运行了几次Perl脚本,我更希望它从命令行参数中获取数据,而不是提示输入。

具有讽刺意味的是,如果使用此处文档,则无法使用输出记录分隔符指定行尾。不需要做任何特别的事情,你可以设置:

代码语言:javascript
复制
$\ = "\r\n";

每个print输出都将以CRLF结束。( $\的默认值是undef,因此默认情况下没有打印为一行结束。)或者,您可以通过以下方法使代码更易于理解:

代码语言:javascript
复制
use English '-no_match_vars';

$ORS = "\r\n";

例如:

代码语言:javascript
复制
#!/usr/bin/env perl
use strict;
use warnings;
use English '-no_match_vars';

print "img URL = ?    ";
my $img = <>;
chomp($img);
print "filename = ?    ";
my $filename = <>;
chomp($filename);

# now write xml with inserted contents to a file:
open my $CARDFILE, ">>", $filename or die "Failed to open file $filename for writing";
my $type = "unregimented";
my $expansion = "contracted";
my $keyword = "lock";
my $color = "green";
my $linkcolor = "blue";
my $kickercolor = "red";
my $cost = '$0.00';
my $strength = "humungous";
my $health = "excellent";

$ORS = "\r\n";

print $CARDFILE "<card>";
print $CARDFILE "    <img>$img</img>";
print $CARDFILE "    <type>$type</type>";
print $CARDFILE "    <expansion>$expansion</expansion>";
print $CARDFILE "    <keyword>$keyword</keyword>";
print $CARDFILE "    <color>$color</color>";
print $CARDFILE "    <linkcolor>$linkcolor</linkcolor>";
print $CARDFILE "    <kickercolor>$kickercolor</kickercolor>";
print $CARDFILE "    <cost>$cost</cost>";
print $CARDFILE "    <strength>$strength</strength>";
print $CARDFILE "    <health>$health</health>";
print $CARDFILE "</card>";

close $CARDFILE;
票数 3
EN

Stack Overflow用户

发布于 2013-07-04 23:56:47

你可以直接

代码语言:javascript
复制
print CARDFILE qq{<card>
<img>$img</img>
<type>$type</type>};

诸若此类。qq告诉Perl对字符串进行内插,因此它与执行“多行字符串”相同。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17479354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档