Perl scripts: requesting for logic explanation


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Perl scripts: requesting for logic explanation
# 1  
Old 02-14-2013
Perl scripts: requesting for logic explanation

Hi,

balajesuri and durden_tyler, I have found your perl script for the thread https://www.unix.com/shell-programmin...ng-string.html, but find it difficult to understand the syntax.

Could you or any forum members kindly shed some light on the logic used in the below Perl scripts?

Code:
perl -ne 'while(/((HOST|PORT) = .+?)\)/g) {print "$1\n"}' $ORACLE_HOME/network/admin/tnsnames.ora
perl -lne 'print "$1\n$2" if /(HOST.*)\)\((PORT.*?)\)/' $ORACLE_HOME/network/admin/tnsnames.ora


Last edited by royalibrahim; 02-14-2013 at 06:39 AM..
# 2  
Old 02-14-2013
The options first:
Code:
-n --> provides you a while loop by reading records (lines (terminated by new-lines) by default)
       from the filename arguments without default printing (similar to sed -n).

-e --> signifies that the next argument is a script/program.

-l --> does automatic line-ending processing. By itself (and with default input separator as 
       new-line), will cause print to automatically add a new-line (spcifically the output 
       record separator which has been assigned the value of current input record separator
       during this switch's processing (Phew...!!!)) after its arguments.

I'll just explain the first one. Hope you can make out the second one on your own.

Read each line of input and try to match the pattern recursively.
I'll rewrite the snippet with the /x modifier to the match operator for explanation:
Code:
perl -ne 'while(
/
(                   ### capturing group 1 starts
 (HOST|PORT)        ### capturing group 2 starts and ends - matches either HOST or PORT
 [ ]=[ ]            ### a space followed by = and then a space
                    ### had to use bracket expressions because white spaces are ignored with x
		    ### modifier
 .+?                ### 1 or more occurrences of any character (.+), non-greedy matching (?)
                    ### non-greedy matching starts matching from the least amount of characters
		    ### possible, as opposed to greedy matching. This ensures that you do not match
		    ### unintended strings.
)                   ### capturing group 1 ends
\)                  ### a literal closing parenthesis
/xg
) {print "$1\n"}' tnsnames.ora

This also exploits a peculiarity/feature of the match operator with the /g modifier.
The match operator with the /g modifier keeps track of where it has matched a pattern in a string
(rather it is the string which keeps track of the same, check perldoc -f pos for details). So, if you
try to match again, it starts from the correct offset.

So, for an input line such as
Code:
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = atoadb01)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = atta1)))

for the first iteration, capturing group 1 matches HOST = atoadb01 and you print it out with $1.
for the second iteration, matching starts from where the 1st one left off. So, capturing group 1 now matches PORT = 1521.
for the third iteration, no match is possible after the second match and the match operator returns false
in the scalar context and you stop processing that line and proceed with the next one.

Last edited by elixir_sinari; 02-14-2013 at 05:50 AM..
This User Gave Thanks to elixir_sinari For This Post:
# 3  
Old 02-14-2013
Here's the original one-liner:

Code:
perl -lne 'print "$1\n$2" if /(HOST.*)\)\((.*?)\)/' input

and here's the only line in the input file on which matches the pattern:

Code:
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = atoadb01)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = atta1)))

Note a few things:

(1) The parentheses "()" without escape back-slashes capture the group of characters and create a backreference.
(2) A parenthesis with an escape back-slash, i.e. either "\(" or "\)" matches a literal parenthesis.
(3) .* matches the maximum sequence of characters (greedy search).
(4) .*? matches the minimum sequence of characters (non-greedy search).

Here's how the regex works. The color of a portion of the regex is the same as the text it matches.

(1)
Code:
/(HOST.*)\)\((.*?)\)/
 
Capture the maximum sequence of characters starting with "HOST".
The following could potentially be stored in $1 so far.
 
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = atoadb01)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = atta1)))

(2)
Code:
/(HOST.*)\)\((.*?)\)/
 
 
Capture the maximum sequence of characters starting with "HOST",
- followed by the literal character ")"
The following could potentially be stored in $1 so far.
 
 
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = atoadb01)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = atta1)))


(3)
Code:
/(HOST.*)\)\((.*?)\)/
 
 
Capture the maximum sequence of characters starting with "HOST",
- followed by the literal character ")"
- followed by the literal character "("
The following could potentially be stored in $1 so far.
 
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = atoadb01)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = atta1)))

(4)
Code:
/(HOST.*)\)\((.*?)\)/
 
 
 
Capture the maximum sequence of characters starting with "HOST",
- followed by the literal character ")"
- followed by the literal character "("
- followed by the minimum sequence of characters till the literal character ")".
 
The following could potentially be stored in $1 and $2 so far.
 
 
 
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = atoadb01)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = atta1)))

Since the pattern has been parsed, we have the values of $1 and $2 now, which we could print.

tyler_durden
This User Gave Thanks to durden_tyler For This Post:
# 4  
Old 02-15-2013
Thanks a tonne elixir_sinari and durden_tyler for the effort and the time that you spent on explaining this code Smilie !! Your lucid explanations are very intuitive and give a clear picture.

@durden_tyler, I just have one trivial question. Why in the script the non-greedy regular expression character '?' is ignored for the "HOST" pattern matching string (when I include it, I get the same correct output yet eager to know why it is not included) also what wrong in explicitly mentioning the "PORT" pattern-matching string in the 2nd back-reference group?
Code:
perl -lne 'print "$1\n$2" if /(HOST.*?)\)\((PORT.*?)\)/' tnsnames.ora


Last edited by royalibrahim; 02-15-2013 at 05:39 AM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Explanation for Scripts Inner Workings Needed

#!/bin/bash n=$l; typeset -a v x=$(< input.dat) check(){ if; then sed 's/Test/Proc/g' file.sh >fl.sh else exit 13 fi } check $n while ; do x=`expr $x -l` v=$x done less fi.sh l>/dev/null&& echo yes || exit 1 echo v= ${v } exit 0 I have file.sh and input.dat in the current... (3 Replies)
Discussion started by: bananasprite
3 Replies

2. Shell Programming and Scripting

Need explanation on Perl Fork

Hi, I am breaking my head to understand the below line of code in perl: next if $pid = fork; # Parent goes to next server. die "fork failed: $!" unless defined $pid; Can anyone please explain me in detail as I am a slow learner? Thanks, Ali. (2 Replies)
Discussion started by: liyakathali
2 Replies

3. Shell Programming and Scripting

Help with Logic - Copying the same files by 2 Linux scripts to same directory

Hi All, Good Morning ! Can anyone help me understand the following scenario. Scenario 1 : 2 LINUX Scripts(Process 1 & 2) are trying to copy the same file (lets call it FileA.txt) to the same directory (lets say, /home/abc/zyz) at the same time. If both copy is happening at the same... (9 Replies)
Discussion started by: dsfreddie
9 Replies

4. Shell Programming and Scripting

Shell/Perl logic for loop

Hi, I have a requirement as follows. Have 3 files. Need to match up the data in each one of them and sum up the data by a field and display it. example given below. File 1 : Name, Emp id File 2 : Empid, Subject, File 3 : Subject, Score, Class Match Emp id in File 1 and File 2 and then... (7 Replies)
Discussion started by: preethgideon
7 Replies

5. Shell Programming and Scripting

Logic Explanation of Match command in Linux

I am debugging a script and have stuck up at one code line awk -F , '{if (match($3,001)) { print $2 } }' Master20120307090511.tmp The Master20120307090511.tmp is 001,ARE , 001 002,ARE , 002 003,ARE , 003 006,ARE , 006 011,ARE , 011 012,ARE , 012 What happens is when i fire this ... (5 Replies)
Discussion started by: vee_789
5 Replies

6. Emergency UNIX and Linux Support

Logic of 3 scripts and 1 header

Hi, I am hitting my head for weeks now, I run 3 sites that are basically serving 1 community, a job search, a wiki and a social networking platform. Rather than promote all three I want to create the illusion that its all 1 website, and I identify 3 areas to make this possible. 1) unified... (7 Replies)
Discussion started by: lawstudent
7 Replies

7. Shell Programming and Scripting

Logic for alert scripts.

Hello, In my system, I have implemented various alerts. An example: #!/bin/sh BILL=bill@company.com #GETS THE CURRENT NO OF SESSIONS OPENED IN ORACLE SESSION_NO=`sqlplus -s ${TEST_USER} <<EOF SET HEAD OFF @/home/alerts/vlib/cur_session_no.sql EOF` #MANUALLY SET A THRESHOLD FOR THE... (1 Reply)
Discussion started by: drbiloukos
1 Replies

8. Shell Programming and Scripting

Requesting full back up scripts

hi guys linux noob here wanting to learn linux scripting, i need help with a backup script that not only allows me to back up my files but restore them to my own personal directory, had a look at some of the coding from the scripts section on this site but still lost. any help is much appreciated (8 Replies)
Discussion started by: burnie35
8 Replies

9. Shell Programming and Scripting

Need explanation on Anonymous hash in PERL!!

Hi, I have doubt regarding the Anonymous hash. For creating a object we are generally using Anonymous hash. My Doubt is: Why we are only using Anonymous hash?? Instead of Anonymous hash can we use global hash variable and take its reference for creating an object using same bless function??... (0 Replies)
Discussion started by: jatanig
0 Replies

10. Shell Programming and Scripting

Shell or PERL Logic

Hello All, Currently i am working on a logic in PERL scripting ... But i am sort of stuck up, can any one please help. Here goes. 1. Search for a pattern in a file 2. If the pattern matched lets say 10 lines 2.1 Reterive the first line and check for another pattern 2.1.1 if... (1 Reply)
Discussion started by: maxmave
1 Replies
Login or Register to Ask a Question