I try to filter expression from a configuration file under Linux mixing bash command line tools and Perl commands in a pipe.
I have a configuration file (see section configuration) and can filter the relevant lines by using `
grep PG.DATABASE database.conf | \
sed -r -e 's/^\s*//;s/\s / /' | \
cut -d ' ' -f2 | \
sort
And get the result as expected:
DB.GRM.CON.LOCAL.V01
DB.GRM.CON.LOCAL.V02
DB.GRM.CON.LOCAL.V03
Now I want to switch to Perl
grep PG.DATABASE database.conf | \
perl -lpe 's/^\s*//; @m = split /\s /; print $m[1]'
but I get strange results with a duplication of the input line.
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
Question
Why is the duplication there and is the correct Perl oneliner for result achieved with the command line tools?
Configuration File
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
CodePudding user response:
I suggest changing the -p option (which makes it automatically print every line) to -n. You can also skip the grep and let perl do it:
perl -lne 'if(/PG\.DATABASE/) {chomp; s/^\s*//; @m = split /\s /; print $m[1]}' database.conf
A simplification could be:
perl -lne 'print $1 if(/PG\.DATABASE:\s(\S )/)' database.conf
CodePudding user response:
I would do:
perl -nE 'say $1 if /^\s PG\.DATABASE:\s (\S )/' file
Which also works in GNU grep:
grep -oP '^\s PG\.DATABASE:\s \K\S ' file
And GNU sed:
sed -nE 's/^\s PG\.DATABASE:\s (\S ).*/\1/p' file
Or POSIX sed:
sed -nE 's/^[[:blank:]]*PG\.DATABASE:[[:blank:]]*([^[:blank:]]*).*/\1/p' file
CodePudding user response:
You can also let perl do the splitting into columns automatically, that might be the correct way to filter columns in perl:
perl -lane 'print $F[1] if $F[0] eq "PG.DATABASE:"' database.conf
DB.GRM.CON.LOCAL.V01
DB.GRM.CON.LOCAL.V02
DB.GRM.CON.LOCAL.V03
