Link to home
Start Free TrialLog in
Avatar of YZlat
YZlatFlag for United States of America

asked on

Need help decyphering ksh script

Here is a piece of ksh script I am trying to understand. I understand that the script reads a file line by line and puts the first part of each line into a variable,  whenever third part of each line equals to "Y".

I just have a few questions about parts of the script. Script is as follows:

cat $FILE1 | while read LINE

do
	
case $LINE in
	
\#*)	# Comment-Line in FILE1
	
;;
	
*) 	# Setup MYVAR 		
# if third field in FILE1 is 'Y'
        
if [ "`echo $LINE | awk -F: '{print $3}' -`" = "Y" ]
	
then
		
MYVAR=`echo $LINE | awk -F: '{print $1}' -`
		
if [ "$MYVAR" = '*' ]
		
then
			
MYVAR=""
		
fi
		

...

esac # End case $LINE

done    # End Loop read FILE1

Open in new window


some questions I have are:

1) in line 5 "case $LINE in", what does it check? Ususally, in other languages, case statement checks multiple cases if a variable equals to some value. here I do not completely understand it

2) In line 7 there is "\#*)" - what does it mean?

3) In line 9 - ";;" what are the two semicolons?

4) in line 11 "*)" ?

5) In line 14:

if [ "`echo $LINE | awk -F: '{print $3}' -`" = "Y" ]

what is the  ` in front of echo do, what is awk-F:
and why '{print $3}' cannot be replaced by just $3?

6) In line 20 what does the if statement check for?

if [ "$MYVAR" = '*' ]
      

I'd really appreciate some help, I am new to ksh scripting
Avatar of ozo
ozo
Flag of United States of America image

man ksh
...
       case word in [ [(]pattern [ | pattern ] ... ) list ;; ] ... esac
              A case command executes the list associated with the first pattern that matches word.  The form of the patterns  is
              the  same as that used for file-name generation (see File Name Generation below).  The ;; operator causes execution
              of case to terminate.  If ;& is used in place of ;; the next subsequent list, if any,  is executed.
...
   Command Substitution.
       The  standard  output  from a command enclosed in parentheses preceded by a dollar sign ( $() ) or a pair of grave accents
       (``) may be used as part or all of a word; trailing new-lines are removed.  In the  second  (obsolete)  form,  the  string
       between  the  quotes  is processed for special quoting characters before the command is executed (see Quoting below).  The
       command substitution $(cat file) can be replaced by the equivalent but faster $(<file).  The command  substitution  $(n<#)
       will expand to the current byte offset for file descriptor n.
man awk
NAME
       awk - pattern-directed scanning and processing language

SYNOPSIS
       awk [ -F fs ] [ -v var=value ] [ 'prog' | -f progfile ] [ file ...  ]

DESCRIPTION
       Awk  scans  each  input  file  for lines that match any of a set of patterns specified literally in prog or in one or more
       files specified as -f progfile.  With each pattern there can be an associated action that will be performed when a line of
       a file matches the pattern.  Each line is matched against the pattern portion of every pattern-action statement; the asso-
       ciated action is performed for each matched pattern.  The file name - means the standard input.   Any  file  of  the  form
       var=value  is treated as an assignment, not a filename, and is executed at the time it would have been opened if it were a
       filename.  The option -v followed by var=value is an assignment to be done before prog  is  executed;  any  number  of  -v
       options may be present.  The -F fs option defines the input field separator to be the regular expression fs.

       An input line is normally made up of fields separated by white space, or by regular expression FS.  The fields are denoted
       $1, $2, ..., while $0 refers to the entire line.  If FS is null, the input line is split into one field per character.

       A pattern-action statement has the form

              pattern { action }

       A missing { action } means print the line; a missing pattern always matches.  Pattern-action statements are  separated  by
       newlines or semicolons.
Avatar of YZlat

ASKER

ozo, could you tell me what exactly each line here does?

case $LINE in      
\#*)            
;;
man [
NAME
     test, [ -- condition evaluation utility

SYNOPSIS
     test expression
     [ expression ]

DESCRIPTION
     The test utility evaluates the expression and, if it evaluates to true, returns a zero (true) exit status; otherwise it
     returns 1 (false).  If there is no expression, test also returns 1 (false).

     All operators and flags are separate arguments to the test utility.

     The following primaries are used to construct expressions:
...
     s1 = s2       True if the strings s1 and s2 are identical.
case $LINE in  
\#*)            
;;
terminates the case statement if $LINE matches the pattern \#*
Avatar of YZlat

ASKER

and what is this pattern?

based on help files I've read, \ makes following characters insignificant

# ia a comment and * I didn't find

what it the pattern "\#*"??

I have read the help file but it was not helpful enough to help me understand the code, that's why i asked the question here. please do not post anymore quotes from help files. Thank you
Avatar of YZlat

ASKER

As I understand, if [ "$MYVAR" = '*' ] checks if any value is assigned to MYVAR. Is that correct? If so, why not just say if $MYVAR is not null?
Avatar of YZlat

ASKER

Also I think I got this part:

case $LINE in
      
\#*)      # Comment-Line in FILE1
      
;;
      
*)

it checks if content of $LINE is a comment - contains #, where \ ensures that compiler does not take the rest of the line for a comment, and if the $LINE is, in fact a comment, it breaks out of the case statement.
*) means if it is anything else, but the comment
Without quoting the documentation, I can't tell you that  *  matches  any string
If you read the documentation but still don't understand the code, that suggests that there could be something you didn't understand about * matches  any string.  
If so, we may be able to clarify if you can help us determine the nature of the misunderstanding.
Avatar of YZlat

ASKER

Looks like I figured most of it out with the help of this tutorial:

http://b62.tripod.com/doc/docksh.htm

Now if you could only help me break this one down:

if [ "`echo $LINE | awk -F: '{print $3}' -`" = "Y" ]

echo $LINE would normally print contents of $LINE to the screen but that does not seem to be the case here

Also awk supposedly scans a file for a pattern but what is -F switch? man awk did not tell me much about switches, -F in particular

And why '{print $3}' -`" = "Y" is used to check if the third part of the string is "Y"? why not just use if[ $3 = "Y"] ??
SOLUTION
Avatar of ozo
ozo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of YZlat

ASKER

But why not just use $3="Y"??

And what does -F switch mean in awk command?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of YZlat

ASKER

Tintin, what does the carrot do?

Also could you please explain to me what does

`echo $LINE

do in line: if [ "`echo $LINE | awk -F: '{print $3}' -`" = "Y" ]

and also why

if [ "$MYVAR" = '*' ]
            
then
                  
   MYVAR=""
            
fi

cannot e re-written as

if [ $MYVAR != ' ' ]
            
then
                  
   MYVAR=""
            
fi
Avatar of YZlat

ASKER

Tintin, I tried

grep "^\*:.*:Y" $FILE1 | while read LINE
do
     echo $LINE
done 

Open in new window


and didn't get any output at all

I also tried

grep "^\*:*:Y" $FILE1 | while read LINE
do
     echo $LINE
done 

Open in new window

and
grep "*:*:Y" $FILE1 | while read LINE
do
     echo $LINE
done 

Open in new window

but nothing gets returned

The exact format of the lines in the input file is

#DBName:/u01/app/oracle/product/11.2.0.3.0:Y
DBName2:/u01/app/oracle/product/11.2.0.3.0:N
DBName3:/u01/app/oracle/product/11.2.0.3.0:Y

from the above I only want

DBName3:/u01/app/oracle/product/11.2.0.3.0:Y

to be returned since it is not commented out and ends with "Y"
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of YZlat

ASKER

Tintin, but it does not necsessary starts with an upper case
Avatar of YZlat

ASKER

I just need to ensure that it does not start with # hash sign

grep -v "^\#"  ensures the line does not start with # sign, but I also need the line to be in the format "dbname:path:Y"

grep "^[a-z]*:.*:Y" $FILE1

worked for me but only for lowercase and grep "^[A-Z]*:.*:Y" $FILE1
worked only for all uppercase. I need it to be case independent
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of YZlat

ASKER

but why is

grep "^\*:.*:Y" $FILE1

not working?

and what is the purpose of the dot (.) in the string above, between : and *
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of YZlat

ASKER

Tintin, what would I use to match a line that can start with any character (except #) but contain colon twice and end with Y?

Example:  xxx:xxxxxx:Y

I tried

grep "^[!#*]:.*:Y" $FILE1

and

grep "^[!#]*:.*:Y" $FILE1

but neither worked
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of YZlat

ASKER

Thank you all!