Print语句在perl的外部块中打印两次

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Print语句在perl的外部块中打印两次相关的知识,希望对你有一定的参考价值。

以下是改编自this link的代码,用于获取天气并在i3blocks上显示。

#!/bin/bash 

METRIC=1 #Should be 0 or 1; 0 for F, 1 for C

if [ -z $1 ]; then
    echo
    echo "USAGE: weather.sh <locationcode>"
    echo
    exit 0;
fi

curl -s http://rss.accuweather.com/rss/liveweather_rss.asp?metric=${METRIC}&locCode=$1 | perl -ne 'use utf8;

if ( /Currently/ ) {

    chomp;
    /<title>Currently: (.*)?</title>/;

    my @values  = split(":", $1); 
    my $deg     = "°C";
    my @values2 = split("C", $values[1]);

    if ( $values[0] eq "Sunny" || $values[0] eq "Mostly Sunny" || $values[0] eq "Partly Sunny" || $values[0] eq "Intermittent Clouds" || $values[0] eq "Hazy Sunshine" || $values[0] eq "Hazy Sunshine" || $values[0] eq "Hot") {
        my $sun = "";
        binmode(STDOUT, ":utf8");
        print "$sun";
    }

    if ( $values[0] eq "Mostly Cloudy" || $values[0] eq "Cloudy" || $values[0] eq "Dreary (Overcast)" || $values[0] eq "Fog" ) {
        my $cloud = "";
        binmode(STDOUT, ":utf8");
        print "$cloud";
    }

    if ( $values[0] eq "Showers" || $values[0] eq "Mostly Cloudy w/ Showers" || $values[0] eq "Partly Sunny w/ Showers" || $values[0] eq "T-Storms"|| $values[0] eq "Mostly Cloudy w/ T-Storms"|| $values[0] eq "Partly Sunny w/ T-Storms"|| $values[0] eq "Rain" ) {
        my $rain = "";
        binmode(STDOUT, ":utf8");
        print "$rain";
    }

    if ( $values[0] eq "Windy" ) {
        my $wind = "";
        binmode(STDOUT, ":utf8");
        print "$wind";
    }

    if ( $values[0] eq "Flurries" || $values[0] eq "Mostly Cloudy w/ Flurries" || $values[0] eq "Partly Sunny w/ Flurries"|| $values[0] eq "Snow"|| $values[0] eq "Mostly Cloudy w/ Snow"|| $values[0] eq "Ice"|| $values[0] eq "Sleet"|| $values[0] eq "Freezing Rain"|| $values[0] eq "Rain and Snow"|| $values[0] eq "Cold" ) {
        my $snow = "";
        binmode(STDOUT, ":utf8");
        print "$snow";
    }

    if ( $values[0] eq "Clear" || $values[0] eq "Mostly Clear" || $values[0] eq "Partly Cloudy"|| $values[0] eq "Intermittent Clouds"|| $values[0] eq "Hazy Moonlight"|| $values[0] eq "Mostly Cloudy"|| $values[0] eq "Partly Cloudy w/ Showers"|| $values[0] eq "Mostly Cloudy w/ Showers"|| $values[0] eq "Partly Cloudy w/ T-Storms"|| $values[0] eq "Mostly Cloudy w/ Flurries" || $values[0] eq "Mostly Cloudy w/ Snow" ) {
        my $night = "";
        binmode(STDOUT, ":utf8");
        print "$night";
    }

    binmode(STDOUT, ":utf8");
    print  "$values2[0]$deg"; 
}'

(可能看起来像方框的文本来自fontawesome字体)。我添加的是以下几行

my $deg = "°C";
my @values2 = split("C",$values[1]);

并修改了最初的print声明,最初是print "$values[1]"。旧的print声明显示没有像35C这样的度数符号的温度。我的意图只是增加像35°C之间的程度,但输出是

35°C°C

为什么子串打印两次?即使我将其包含在单独的print语句中或直接包含子字符串(print $values2[0]°C),也会发生这种情况。

奇怪的是,包括print "$sun$values2[0]$deg";等内部区块的价值和单位似乎工作正常,没有重复。

答案

该脚本的工作原理是在RSS中查找<title>标记。如果你手动完成,你会看到有几个。

curl -s 'http://rss.accuweather.com/rss/liveweather_rss.asp?metric=1&locCode=ASI|IN|IN031|MADRAS' | grep title
<title>Madras, IN - AccuWeather.com Forecast</title>
            <title>Madras, IN - AccuWeather.com Forecast</title>
            <title>Currently: Partly Sunny: 35C</title> 
                <title>5/23/2018 Forecast</title>
                <title>5/24/2018 Forecast</title>
<title>The AccuWeather.com RSS Center</title>

如果你添加

use strict;
use warnings;

你会收到大量关于未定义变量的警告。那是因为它没有找到与该模式的标题匹配,但它仍然打印。

  if (/Currently/) {
    chomp;
    /<title>Currently: (.*)?</title>/;

    # ....
    print "$values2[0]$deg";
  }

这也是你获得额外输出的原因。

如果没有匹配,您需要跳过该行。

/<title>Currently: (.*)?</title>/ or next;

以上是关于Print语句在perl的外部块中打印两次的主要内容,如果未能解决你的问题,请参考以下文章

在perl中用引号打印@

python条件判断语句

为啥我的代码在完成块中运行两次

关于字符编码的Python和Perl打印的区别

为啥 PowerShell(使用 Perl)在简单的打印语句中删除双引号?

为啥使用管道在 IPC 中使用 write() 而不是 print() 打印输出两次?