从多线文本中提取字段,该文本通过管道传输到Perl中

时间:2017-12-14 14:46:01

标签: regex postgresql perl

我想从以下类型的输入中提取一个数字(在此示例中为7):

 received_tli 
--------------
            7
(1 row)

对于多行字符串作为Perl变量存在的情况,我看过recipes。但是,我更喜欢调用这样的表达式:

psql -c "SELECT received_tli FROM pg_stat_wal_receiver" | \
  perl -e 'print $1 if /<expression>/'

我已尝试过,例如\s^received_tli\s*\n-+\n\s*([0-9])+\s*\n(1 row)作为表达式,但这似乎不起作用。如何使用(多行)正则表达式解析通过管道传输到Perl的多行输入?

3 个答案:

答案 0 :(得分:2)

您使用perl -e时遇到的问题是,您在任何时候都没有阅读STDIN,因此perl没有“看到”您的数据。

您可以使用-ne告诉perl将您的代码段包装在while ( <> ) { }循环中。这可能是有限的用途,因为它是逐行工作的。

那么你需要设置'行尾分隔符'(-0标志)然后应用你的正则表达式:

perl -0777 -ne 'print $1 if m/received_tli\D*(\d+)/' 

或者用更长的perl脚本编写(但希望更具可读性):

#!/usr/bin/perl
use strict;
use warnings;

local $/;
while (<>) {
   print $1,"\n" if m/received_tli\D*(\d+)/;
}

答案 1 :(得分:1)

根本不需要涉及Perl。只需使用-t中的--tuples-onlypsql选项:

即可
psql -t -c "SELECT received_tli FROM pg_stat_wal_receiver"

答案 2 :(得分:0)

从您的示例数据中,您看起来想要在仅包含该整数和一些空格的行上使用整数。所以这样的事情会起作用:

#!/usr/bin/perl

use strict;
use warnings;

while (<>) {
  /^\s*(\d+)\s*$/ and print $1;
}

您可以将其放入文件中,使其可执行,然后使用以下命令运行:

$ psql ... | your_extract_program

但是如果你真的想每次都重新输入Perl代码,你可以使用:

$ psql ... | perl -n -e 'print $1 if /^\s*(\d+)\s*$/'