【问题标题】:Awk's output in Perl doesn't seem to be working properlyawk 在 Perl 中的输出似乎不能正常工作
【发布时间】:2018-06-04 21:22:18
【问题描述】:

我正在编写一个简单的 Perl 脚本,用于输出外部文本文件的第二列(第一列和第二列用逗号分隔)。

我使用 AWK 是因为我熟悉它。

这是我的脚本:

use v5.10;
use File::Copy;
use POSIX;

$s = `awk -F ',' '\$1==500 {print \$2}' STD`;
say $s;

本地文件“STD”的内容是:

CIR,BS  
60,90
70,100
80,120
90,130
100,175
150,120
200,260
300,500
400,600
500,850
600,900

我的输出很奇怪,它打印出所需的“850”,但它也打印了行尾和新行!

ka@man01:$ ./test.pl 
850

ka@man01:$

问题不只是打印。我需要使用由 awk 生成的变量“即 $s 变量),但该变量也被保留了一个长字符串和一个新行!

你们能帮忙吗?

谢谢。

【问题讨论】:

  • 你为什么要将awk 内联到 perl 中?
  • @RavinderSingh13 当我用 "chomp $s" Can't modify scalar chomp in scalar assignment at ./test.pl line 7, near "awk -F ',' '\$1==500 {print \$2}' STD@987654326 声明 $s 时,它抛出了一条错误消息@
  • @Sobrique 我不是 Perl 专家,所以我不知道 Perl 是否有内置函数可以打开远程文件,搜索它,找到一个字符串,然后编写它变成一个变量。
  • 您将文本文件STD 描述为外部文件本地文件远程文件我>。你说所有这些是什么意思?当然,它们不能同时全部为真吗?为什么不只是一个文件?
  • “这个变量也被一个长字符串保留”

标签: perl awk


【解决方案1】:

我建议您首先尝试将awk 内联到perl 中,从而走上一条肮脏的道路。为什么不呢:

open ( my $input, '<', 'STD' ) or die $!;
while ( <$input> ) {
    s/\s+\z//;
    my @fields = split /,/; 
    print $fields[1], "\n" if $fields[0] == 500; 
} 

但可能的问题是您没有处理换行符,而say 正在添加一个额外的换行符。尝试改用print,或在结果字符串上使用chomp

【讨论】:

  • 感谢您的反馈 Sobrique。无论我使用“say”还是“print”,该变量都是要写入外部文件的,并且仍然以空格和换行符显示。感谢您发布建议的脚本。它不起作用!因为它打印空白空间。
  • split 必须是 split /,/ 或类似的
  • @Borodin,这就像一个魅力!谢谢你。现在很抱歉这么痛苦,为什么变量仅在循环内局部显着?即使我在 while 循环之外声明“字段”变量,我也无法让它工作。我想在循环外使用变量的值。谢谢。
【解决方案2】:

perl 可以做许多 awk 可以做的事情。下面是替换整个 Perl 程序的类似内容:

$ perl -naF, -le 'chomp; print $F[1] if $F[0]==500' STD
850

-n 围绕您对-e 的参数创建一个while 循环。

-a 将每一行拆分为@F-F 允许您指定分隔符。由于您想用逗号分隔字段,因此请使用 -F,

每次调用 print 时,-l 都会添加一个换行符。

-e 参数是要运行的程序(加上来自-nwhile)。 chomp 从输出中删除换行符。您在输出中得到一个换行符,因为您碰巧使用了该行中的最后一个字段。 -l 打印时添加换行符;当您要提取行中间的字段时,这一点很重要。

【讨论】:

  • 我不确定用 perl 比用 awk 更可取!
  • 但是 OP 说他们 “需要使用 awk 生成的变量”,即$s 变量)" 所以这只是 Perl 程序的一部分。听起来他们应该将文件读入哈希中。
  • 你为什么要chomp-l在一起?
  • chomp 删除不属于最后一条记录的换行符,而只是一个行分隔符。 -l 为您决定打印的任何列添加换行符(即使它不是最后一列)。这是答案的最后一段。
【解决方案3】:

你得到 2 个换行符的原因:

  1. 反引号运算符不会从 awk 输出中删除尾随换行符。 $s 包含 "850\n"
  2. say 函数将换行符附加到字符串。您有 say "850\n"print "850\n\n" 相同

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-16
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 2012-05-06
    相关资源
    最近更新 更多