Parsing a control file loop


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Parsing a control file loop
# 8  
Old 05-14-2018
Enclose the $line in double quote to have the shell preserve spaces within.

But, I may be thick-witted, but the entire problem escapes me, even with the new sample.
OK, you have the OS - however determined - in the first field. What is the second field for? And, why not just list the commands to be executed in a list right after the OS paragraph header?

Please give some consistent context / background to help people understand what you're after. The HP-UX problem from post#1 seems to have disappeared in the new sample?
This User Gave Thanks to RudiC For This Post:
# 9  
Old 05-14-2018
Quote:
Originally Posted by RudiC
Enclose the $line in double quote to have the shell preserve spaces within.

But, I may be thick-witted, but the entire problem escapes me, even with the new sample.
OK, you have the OS - however determined - in the first field. What is the second field for? And, why not just list the commands to be executed in a list right after the OS paragraph header?

Please give some consistent context / background to help people understand what you're after. The HP-UX problem from post#1 seems to have disappeared in the new sample?
The script is for modifying a specific configuration file (ps_mon.cfg) on different servers. The 2nd field is there, so that the script will search for that keyword first in the config file, and if there's an *ACTION already added in the next line after that keyword, will not proceed on executing the command in the 3rd field. Otherwise, the script will execute the command to insert that *ACTION line after the keyword. Obviously, I have those sorted in, though I'm open to suggestions if you have simpler code since I'm a clunky coder.

Once the script got the OS of the server it will execute on, for example RHEL, how can I get only the lines with RHEL, then assign the second field to $PROCESS and the third field to $COMMAND in a loop, so that I can accomplish the above?
# 10  
Old 05-14-2018
One comment:
assuming there is embedded sed code, then
Code:
 's/^syslogd.*$/&\n*ACTION \/etc\/init.d\/syslog start/'

substitutes the current line by itself plus a new line.
This is the same as appending a new line, and the a command does it nicely
Code:
 '/^syslogd/ a*ACTION /etc/init.d/syslog start'

And no backslashes needed!
This User Gave Thanks to MadeInGermany For This Post:
# 11  
Old 05-14-2018
The following file has another separator at the end of the command field
Code:
RHEL:syslogd:sed -i '/^syslogd/ a*ACTION /etc/init.d/syslog start/' $CFG_DIR/ps_mon.cfg:
RHEL:ntpd:"sed -i '/^ntpd/ a*ACTION \/etc\/init.d\/ntpd start/' $CFG_DIR/ps_mon.cfg:
RHEL:scopeux:"sed -i '/^scopeux/ a*ACTION /opt/perf/bin/ovpa start all/' $CFG_DIR/ps_mon.cfg:

SUSE:cron:"sed -i '/^cron/ a*ACTION /etc/init.d/cron start/' $CFG_DIR/ps_mon.cfg:
SUSE:scopeux:"sed -i '/^scopeux/ a*ACTION /opt/perf/bin/ovpa start all/' $CFG_DIR/ps_mon.cfg:
SUSE:midaemon:"sed -i '/^midaemon/ a*ACTION /opt/perf/bin/ovpa start all/' $CFG_DIR/ps_mon.cfg:

HP-UX:scopeux:file=$CFG_DIR/ps_mon.cfg; sed 's/^scopeux/ a\
*ACTION /opt/perf/bin/ovpa start all' "$file" > "$file".tmp && mv "$file".tmp "$file":
HP-UX:midaemon:file=$CFG_DIR/ps_mon.cfg; sed '/^midaemon/ a\
*ACTION /opt/perf/bin/ovpa start all' "$file" > "$file".tmp && mv "$file".tmp "$file":
HP-UX:perfalarm:file=$CFG_DIR/ps_mon.cfg; sed '/^perfalarm/ a\
*ACTION /opt/perf/bin/ovpa start all' "$file" > "$file".tmp && mv "$file".tmp "$file":

It can be parsed by the following Bourne-compatible shell script
Code:
#!/bin/sh
PATH=/bin:/usr/bin
sep=":"
while IFS=$sep read -r f1 f2 f3
do
  [ -n "$f1" ] || continue
  cmd=$f3
  while
    case $cmd in
    (*$sep) break;;
    esac
  do
    read line
    cmd="$cmd
$line"
  done
  cmd=`expr X"$cmd" : X"\(.*\)$sep"` 
  echo "\
field1 = $f1
field2 = $f2 
cmd = $cmd"
done

The good thing is, the command can contain any characters: \n or newlines, and all quoting characters, and even the : character!
NB the shell script reads from stdin. Run it with /bin/sh /path/to/script < input_file.

Last edited by MadeInGermany; 05-14-2018 at 02:43 PM..
This User Gave Thanks to MadeInGermany For This Post:
# 12  
Old 05-22-2018
Quote:
Originally Posted by MadeInGermany
The following file has another separator at the end of the command field
Code:
RHEL:syslogd:sed -i '/^syslogd/ a*ACTION /etc/init.d/syslog start/' $CFG_DIR/ps_mon.cfg:
RHEL:ntpd:"sed -i '/^ntpd/ a*ACTION \/etc\/init.d\/ntpd start/' $CFG_DIR/ps_mon.cfg:
RHEL:scopeux:"sed -i '/^scopeux/ a*ACTION /opt/perf/bin/ovpa start all/' $CFG_DIR/ps_mon.cfg:

SUSE:cron:"sed -i '/^cron/ a*ACTION /etc/init.d/cron start/' $CFG_DIR/ps_mon.cfg:
SUSE:scopeux:"sed -i '/^scopeux/ a*ACTION /opt/perf/bin/ovpa start all/' $CFG_DIR/ps_mon.cfg:
SUSE:midaemon:"sed -i '/^midaemon/ a*ACTION /opt/perf/bin/ovpa start all/' $CFG_DIR/ps_mon.cfg:

HP-UX:scopeux:file=$CFG_DIR/ps_mon.cfg; sed 's/^scopeux/ a\
*ACTION /opt/perf/bin/ovpa start all' "$file" > "$file".tmp && mv "$file".tmp "$file":
HP-UX:midaemon:file=$CFG_DIR/ps_mon.cfg; sed '/^midaemon/ a\
*ACTION /opt/perf/bin/ovpa start all' "$file" > "$file".tmp && mv "$file".tmp "$file":
HP-UX:perfalarm:file=$CFG_DIR/ps_mon.cfg; sed '/^perfalarm/ a\
*ACTION /opt/perf/bin/ovpa start all' "$file" > "$file".tmp && mv "$file".tmp "$file":

It can be parsed by the following Bourne-compatible shell script
Code:
#!/bin/sh
PATH=/bin:/usr/bin
sep=":"
while IFS=$sep read -r f1 f2 f3
do
  [ -n "$f1" ] || continue
  cmd=$f3
  while
    case $cmd in
    (*$sep) break;;
    esac
  do
    read line
    cmd="$cmd
$line"
  done
  cmd=`expr X"$cmd" : X"\(.*\)$sep"` 
  echo "\
field1 = $f1
field2 = $f2 
cmd = $cmd"
done

The good thing is, the command can contain any characters: \n or newlines, and all quoting characters, and even the : character!
NB the shell script reads from stdin. Run it with /bin/sh /path/to/script < input_file.
Thank you very much for this input. I apologize if I wasn't able to reply in the past few days. I got sick.

I haven't tested it yet, but will do today and let you know how it goes.

---------- Post updated at 11:00 AM ---------- Previous update was at 10:33 AM ----------

Ok tested the code at last, and while the parsing works pretty well, the variable $CFG_DIR is taken literally and I can't substitute any value for it. So when I try to execute the $cmd, I get the error "$CFG_DIR/ps_mon.cfg not found".

This is the only problem I have left, and once it's solved then I can finish the script.

Last edited by The Gamemaster; 05-22-2018 at 12:00 AM..
# 13  
Old 05-22-2018
Quote:
Originally Posted by The Gamemaster
Ok tested the code at last, and while the parsing works pretty well, the variable $CFG_DIR is taken literally and I can't substitute any value for it. So when I try to execute the $cmd, I get the error "$CFG_DIR/ps_mon.cfg not found".
For this kind of situations there is the eval keyword. Its use is always the last resort, so this is not a "recommendation" and the advice is to handle it with extreme care.

Since you don't show us your code you will have to find out how to incorporate it yourself. Just so much: basically it starts the parsing of the command line a second time. Here is an example what that means:

Code:
var="abc"
abc="123"
print - $$var

Now, this will NOT work. One might expect that "$var" is expanded to "abc" and "$abc" is expanded to "123", but this is not the case. In fact all variables are expanded at the same time and once they are - they are. There is no going back and expanding a second time.

In comes eval. This indeed starts the whole parsing process a second time and hence:

Code:
var="abc"
abc="123"
eval print - \$$var

will do the second indirection. This now works exactly like described above. Notice that the first "$" had to be escaped to protect it from being interpreted in the first parsing pass.

I hope this helps.

bakunin
This User Gave Thanks to bakunin For This Post:
# 14  
Old 05-22-2018
Quote:
Originally Posted by bakunin
For this kind of situations there is the eval keyword. Its use is always the last resort, so this is not a "recommendation" and the advice is to handle it with extreme care.

Since you don't show us your code you will have to find out how to incorporate it yourself. Just so much: basically it starts the parsing of the command line a second time. Here is an example what that means:

Code:
var="abc"
abc="123"
print - $$var

Now, this will NOT work. One might expect that "$var" is expanded to "abc" and "$abc" is expanded to "123", but this is not the case. In fact all variables are expanded at the same time and once they are - they are. There is no going back and expanding a second time.

In comes eval. This indeed starts the whole parsing process a second time and hence:

Code:
var="abc"
abc="123"
eval print - \$$var

will do the second indirection. This now works exactly like described above. Notice that the first "$" had to be escaped to protect it from being interpreted in the first parsing pass.

I hope this helps.

bakunin
This basically solved it. Thanks so much for everyone's help here.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Parsing log file and print latest number in loop

Hello All, I have an awk script which parses my log file and prints number grepping from a specific line/pattern, now i have to come with a shell script to continue reading the log untill the job is completed, which i would know while reading session log untill process encounters a final... (1 Reply)
Discussion started by: Ariean
1 Replies

2. Shell Programming and Scripting

Check and control params in parsing file

Hello, I would like to control and check the right parameters $1 must have 4 alphabetics digits among eora qora pora fora $2 must have 2 numerics digits 00 to 11 $3 must have 2 numerics digits 00 to 59 $4 must have 10 characters alpha numerics as 2013-02-26 For example : In case 5) if i... (15 Replies)
Discussion started by: amazigh42
15 Replies

3. Shell Programming and Scripting

Check and control params in parsing file

Hello, I would like to control and check the right parameters $1 must have 4 alphabetics digits among eora qora pora fora $2 must have 2 numerics digits 00 to 11 $3 must have 2 numerics digits 00 to 59 $4 must have 10 characters alpha numerics as 2013-02-26 For example : In case 5) if i... (1 Reply)
Discussion started by: amazigh42
1 Replies

4. Shell Programming and Scripting

Loop exit control

Hi I would like to exit the loop below on <Enter> even if it sleeps. Is it possible? while true do my_procedure; sleep 60 done Thanks (7 Replies)
Discussion started by: zam
7 Replies

5. UNIX for Dummies Questions & Answers

For loop control with two variables in csh shell

Hi All How can i control for loop with two different variables in csh shell Regards Nikhil (1 Reply)
Discussion started by: Nikhilindurkar
1 Replies

6. Shell Programming and Scripting

Parsing of file for Report Generation (String parsing and splitting)

Hey guys, I have this file generated by me... i want to create some HTML output from it. The problem is that i am really confused about how do I go about reading the file. The file is in the following format: TID1 Name1 ATime=xx AResult=yyy AExpected=yyy BTime=xx BResult=yyy... (8 Replies)
Discussion started by: umar.shaikh
8 Replies

7. Shell Programming and Scripting

Control Not Coming Out Of While Loop

I have an empty .gz file in archival directory. And I am redirecting to a dat file. My while loop is not getting ended. I need the solution. cnt=0 while read line do cnt=`expr $cnt + 1` echo "$ARCH_DIR/$line.gz" >> $DATA_DIR/$FILE_LIST_FILE_FEB FILE_NAMES=${FILE_NAMES}"... (2 Replies)
Discussion started by: vinodh1978
2 Replies

8. Shell Programming and Scripting

for loop control

Hi, I have taken a piece of code from a book, which is working as per the specification. The code.... for entry in * do if then echo $entry fi done The sub-directories present in the current directory will be displayed while executing. ... (3 Replies)
Discussion started by: saravanakumar
3 Replies

9. Shell Programming and Scripting

find command in while loop - how to get control when no files found?

I have the following statement in script: find ${LANDING_FILE_DIR}${BTIME_FILENAME_PATTERN2} -print | while read file; do ... done When there are no files located by the find comand it returns: "find: bad status-- /home/rnitcher/test/....." to the command line How do I get control in... (3 Replies)
Discussion started by: mavsman
3 Replies

10. Shell Programming and Scripting

sending control c in the loop

I want to go through the list of items and run it. while running it, some of them will have either >there is no response # and then end it... so that it can go to next item OR >there is response # but in order to break out of it, u need to do Control c. How do you send control... (6 Replies)
Discussion started by: hankooknara
6 Replies
Login or Register to Ask a Question