使用 Perl 的列过滤器表达式的正确在线者是什么?

huc*_*inn 2 bash perl command-line

我尝试在 Linux 下混合 bash 命令行工具和管道中的 Perl 命令来过滤配置文件中的表达式。

我有一个配置文件(请参阅配置部分),可以使用 ` 过滤相关行

grep PG.DATABASE database.conf | \
sed -r -e 's/^\s*//;s/\s+/ /'  | \
cut -d ' ' -f2 | \
sort
Run Code Online (Sandbox Code Playgroud)

并得到预期的结果:

DB.GRM.CON.LOCAL.V01
DB.GRM.CON.LOCAL.V02
DB.GRM.CON.LOCAL.V03
Run Code Online (Sandbox Code Playgroud)

现在我想切换到 Perl

DB.GRM.CON.LOCAL.V01
DB.GRM.CON.LOCAL.V02
DB.GRM.CON.LOCAL.V03
Run Code Online (Sandbox Code Playgroud)

但由于输入行重复,我得到了奇怪的结果。

DB.GRM.CON.LOCAL.V01
PG.DATABASE: DB.GRM.CON.LOCAL.V01 BEGIN
DB.GRM.CON.LOCAL.V02
PG.DATABASE: DB.GRM.CON.LOCAL.V02 BEGIN
DB.GRM.CON.LOCAL.V03
PG.DATABASE: DB.GRM.CON.LOCAL.V03 BEGIN
Run Code Online (Sandbox Code Playgroud)

问题

为什么会出现重复,并且使用命令行工具获得的结果是否是正确的 Perl oneliner?

配置文件

PG.CONFIG: DEFAULT BEGIN

   # Green Rebel Database via PG.SERVICE ------------------------
   PG.DATABASE: DB.GRM.CON.LOCAL.V01 BEGIN
     SERVICE:     'LOC-GRM-V0'
   END.DB.GRM.CON.LOCAL.V01

   # Green Rebel Database via DBI Driver ------------------------
   PG.DATABASE: DB.GRM.CON.LOCAL.V02 BEGIN
     DBI.PG: "dbi:Pg:dbname=grm;host=localhost;port=5432"
     AUTO.COMMIT: FALSE
     RAISE.ERROR: TRUE
     PRINT.ERROR: FALSE
   END.DB.GRM.CON.LOCAL.V02

   # Green Rebel Database via Host, Db, User, Pass --------------
   PG.DATABASE: DB.GRM.CON.LOCAL.V03 BEGIN
     SERVER:     'localhost'
     PORT:        5432
     DATABASE:    'grm'
     USER:        ${/SYSTEM/USER}
     SSL.MODE:    allow
     AUTO.COMMIT: FALSE
     RAISE.ERROR: TRUE
     PRINT.ERROR: FALSE
   END.DB.GRM.CON.LOCAL.V03
END.DEFAULT

Run Code Online (Sandbox Code Playgroud)

Ted*_*gmo 5

我建议将该-p选项(使其自动打印每一行)更改为-n. 你也可以跳过grep并让它perl做:

perl -lne 'if(/PG\.DATABASE/) {chomp; s/^\s*//; @m = split /\s+/; print $m[1]}' database.conf
Run Code Online (Sandbox Code Playgroud)

一个简化可以是:

perl -lne 'print $1 if(/PG\.DATABASE:\s(\S+)/)'  database.conf
Run Code Online (Sandbox Code Playgroud)