Hard time with scripting in OpenVMS - openvms

I am having a very hard time with scripting in OpenVMS
I have a certain output in a file called test.txt .For example :
[WWEWE#http-lx-as code]$ cat test.txt
** Configuration for file "MULTINET:NETWORK_DEVICES.CONFIGURATION" **
Device Adapter CSR Address Flags/Vector
------ ------- ----------- ------------
se0 (Shared VAX/VMS Ethernet) -NONE- -NONE- -NONE-
s10 (Serial Line IP) -NONE- -NONE- -NONE-
dn0 (IP over DECNet link) -NONE- -NONE- -NONE-
I have written a script in Linux which helps to pick up all the information under the device column in this case se0,s10,dn0.
Can we do a similar thing in OPEN VMS
The Linux script is as follows :
SCRIPT :
for i in `cat test.txt 2>/dev/null |egrep '^[a-z]' |grep -v '\*\*' | awk '{print $1}'`
> do
> echo Begin-interface: $i
> done
OUTPUT :
Begin-interface: se0
Begin-interface: s10
Begin-interface: dn0
Let me know if it can be achieved,
Thanking you in advance

Assuming that you need anything in the first column below the line starting with '-'
you can try the following in a command file, e.g. extract_if.com
$ IF P1 .EQS. "" THEN GOTO nothing_specified
$ IF F$SEARCH( P1 ) .EQS. "" THEN GOTO file_not_found
$ parse_line = 0
$ OPEN/READ/ERROR=file_open_error infile 'P1'
$read_loop:
$ READ/ERROR=file_read_error/END_OF_FILE=end_of_file infile inline
$ IF F$LENGTH( F$EDIT( inline, "TRIM" ) ) .EQ. 0 THEN GOTO read_loop
$ IF parse_line .EQ. 1
$ THEN
$ interface = F$ELEMENT( 0, " ", F$EDIT( inline, "TRIM,COMPRESS" ) )
$ WRITE SYS$OUTPUT F$FAO( "Begin-interface: !AS", interface )
$ ELSE
$ parse_line = ( F$EXTRACT( 0,1,inline ) .EQS. "-" )
$ ENDIF
$ GOTO read_loop
$nothing_specified:
$ WRITE SYS$OUTPUT "No file specified"
$ GOTO finished
$file_not_found:
$ WRITE SYS$OUTPUT F$FAO( "File !AS not found", P1 )
$ GOTO finished
$file_open_error:
$ WRITE SYS$OUTPUT F$FAO( "Error opening file !AS", P1 )
$ GOTO finished
$file_read_error:
$ WRITE SYS$OUTPUT F$FAO( "Error reading from file !AS", P1 )
$ GOTO close_file
$end_of_file:
$close_file:
$ IF F$TRNLNM("infile").NES."" THEN CLOSE infile
$finished:
$ EXIT
Run this script using:
$ #extract_if test.txt
The output should be as specified.
It seems you are familiar with AWK. You can also install GAWK for OpenVMS.

Two years late....
$ gawk/comm="/^[a-z]/{print ""Begin-interface:"",$1}" test.tmp
Begin-interface: se0
Begin-interface: s10
Begin-interface: dn0
Guess I will never understand those Unix script weenies which think they need 4 or 5 piped commands, then the proper tool and do everything in one step.
Piping 'cat' output into awk or perl is the most obvious and obnoxious sign of clueless-ness.
Oh well... Onwards!
Hein.

Related

OpenVMS - Trying to create an action for invalid selection

I'm trying to write a simple .com file that will give the user a choice to open files from a pick list. It opens the files fine when you select the number, but if you select an invalid choice, it should loop you back to the pick list. That is not working.
I've been looking at the OpenVMS User's Manual but have been unable to resolve this.
$! CHOICE.COM
$! Test file to offer choice to open one of two files
$!
$ ON WARING THEN EXIT
$ HOME:
$ WRITE SYS$OUTPUT “”
$ WRITE SYS$OUTPUT “1 – FILEA”
$ WRITE SYS$OUTPUT “2 – FILEZ”
$ WRITE SYS$OUTPUT “”
$ WRITE SYS$OUTPUT “”
$ INQUIRE P1 “Enter the number of the file to open or type X to exit:”
$ IF P1.EQS.”1”
$ THEN
$ #FILEA.COM
$ ENDIF
$ IF P1.EQS.”2”
$ THEN
$ #FILEZ.COM
$ ENDIF
$ IF P1.EQS.”X”
$ THEN
$ EXIT
$ IF P1.EQS.””
$ THEN
$ WRITE SYS$OUTPUT “Invalid Choice – try again!”
$ WAIT 0:0:5
$ GOTO HOME
$ ENDIF
$ !
I expect an invalid choice to return the user to HOME:
OK, with a little help from a programmer, I have the answer.
$! CHOICE.COM
$! Test file to offer choice to open one of two files
$!
$ ON WARING THEN EXIT
$ HOME:
$ WRITE SYS$OUTPUT ""
$ WRITE SYS$OUTPUT "1 - FILEA"
$ WRITE SYS$OUTPUT "2 - FILEZ"
$ WRITE SYS$OUTPUT ""
$ WRITE SYS$OUTPUT ""
$ INQUIRE P1 "Enter the number of the file to open or type X to exit:"
$ IF P1.EQS."1"
$ THEN
$ #FILEA
$ EXIT
$ ENDIF
$ IF P1.EQS."2"
$ THEN
$ #FILEZ
$ EXIT
$ ENDIF
$ IF P1.EQS."X" THEN EXIT
$ WRITE SYS$OUTPUT "Invalid Choice - try again!"
$ WAIT 0:0:5
$ GOTO HOME

Linux simple while loop

I have log file keep updating for 30 minutes and I implement script which will check that log file till it has "success" message written in it.So far I have implemented below.Any help or correction would be appreciated.
while [ "($cat R12TECH2.log | grep 'success')" != " " ]
do
echo "Please wait...devccm Adautoconfig is still running..."
sleep 5
done
echo "Status of devccm adautoconfig"
cat R12TECH2.log | grep 'success'
exit
Replace
while [ "($cat R12TECH2.log | grep 'success')" != " " ]
With:
while ! grep -q 'success' R12TECH2.log
The while statement does not require a [...] statement. It will work with any command that provides a satisfactory exit code. grep is one such command. Since we don't care about the output of the grep command, we use -q to silence it.
Grep and exit codes
Consider the test file:
$ cat R12TECH2.log
line 1
success
line 3
This grep command returns success (0):
$ grep -q 'success' R12TECH2.log; echo code=$?
code=0
We, however, want the while loop to run only if success is not in the file. Thus, provide a leading ! which tells the shell to negate the exit code:
$ ! grep -q 'success' R12TECH2.log; echo code=$?
code=1

A script to change file names

I am new to awk and shell based programming. I have a bunch of files name file_0001.dat, file_0002.dat......file_1000.dat. I want to change the file names such as the number after file_ will be a multiple of 4 in comparison to previous file name. SO i want to change
file_0001.dat to file_0004.dat
file_0002.dat to file_0008.dat
and so on.
Can anyone suggest a simple script to do it. I have tried the following but without any success.
#!/bin/bash
a=$(echo $1 sed -e 's:file_::g' -e 's:.dat::g')
b=$(echo "${a}*4" | bc)
shuf file_${a}.dat > file_${b}.dat
This script will do that trick for you:
#!/bin/bash
for i in `ls -r *.dat`; do
a=`echo $i | sed 's/file_//g' | sed 's/\.dat//g'`
almost_b=`bc -l <<< "$a*4"`
b=`printf "%04d" $almost_b`
rename "s/$a/$b/g" $i
done
Files before:
file_0001.dat file_0002.dat
Files after first execution:
file_0004.dat file_0008.dat
Files after second execution:
file_0016.dat file_0032.dat
Here's a pure bash way of doing it (without bc, rename or sed).
#!/bin/bash
for i in $(ls -r *.dat); do
prefix="${i%%_*}_"
oldnum="${i//[^0-9]/}"
newnum="$(printf "%04d" $(( 10#$oldnum * 4 )))"
mv "$i" "${prefix}${newnum}.dat"
done
To test it you can do
mkdir tmp && cd $_
touch file_{0001..1000}.dat
(paste code into convert.sh)
chmod +x convert.sh
./convert.sh
Using bash/sed/find:
files=$(find -name 'file_*.dat' | sort -r)
for file in $files; do
n=$(sed 's/[^_]*_0*\([^.]*\).*/\1/' <<< "$file")
let n*=4
nfile=$(printf "file_%04d.dat" "$n")
mv "$file" "$nfile"
done
ls -r1 | awk -F '[_.]' '{printf "%s %s_%04d.%s\n", $0, $1, 4*$2, $3}' | xargs -n2 mv
ls -r1 list file in reverse order to avoid conflict
the second part will generate new filename. For example: file_0002.dat will become file_0002.dat file_0008.dat
xargs -n2 will pass two arguments every time to mv
This might work for you:
paste <(seq -f'mv file_%04g.dat' 1000) <(seq -f'file_%04g.dat' 4 4 4000) |
sort -r |
sh
This can help:
#!/bin/bash
for i in `cat /path/to/requestedfiles |grep -o '[0-9]*'`; do
count=`bc -l <<< "$i*4"`
echo $count
done

Awk or grep question

I have this datafile
[abc]
def
ghi
[jkl]
[mno]
From this file; i can run grep and easily get all lines that have "[" in them. How can I get the contents of text inside "[]".
For example:
abc
jkl
mno
Thanks
Give this a try:
sed -n 's/\[\([^]]*\)\]/\1/p'
or
awk -F "[][]" '$2 != "" {print $2}'
or
grep -Po '(?<=\[)[^]]*(?=])'
sed -n 's/\[\(.*\)\]/\1/p' file
Explanation: -n suppresses the printing of each line to STDOUT, but the /p at the end of the regex re-enables this behavior causing all matching lines to be printed. The regex itself matches everything between brackets and replaces the entire line with it.
grep "\[" | sed -e 's/\[//' -e 's/\]//'
here's how you can do it with awk
$ cat file
[abc]
def [ xxx]
ghi
[jkl]
[mno]
[zz
zzzz]
$ awk 'BEGIN{RS="]";FS="["}/\[/{print $NF }' file
abc
xxx
jkl
mno
zz
zzzz
Ruby(1.9+)
ruby -0777 -ne 'puts $_.scan(/\[(.*?)\]/m)' file
Or you can do it with just the shell
$ var=$(<file)
$ IFS="]"
$ set -- $var
$ for i in $#; do echo ${i##*[}; done

Whats wrong with this C shell script?

I am trying to write a C shell equivalent script for the bash script mentioned here.
This is what I have :
#! /bin/tcsh
set now=`date +%Y%m%d%H%M.%S`
if (( ! -f "./cache" ) || (-n "`find ./monme -newer ./cache`" ))
then
touch cache -t "$now"
echo "new files added" | mail -s "new build" myemail#myserver.com
endif
and this is the error I get
$ ./scr
if: Badly formed number.
$
This page mentions that "Numbers in the C-shell must be integers", so I tried
set now=`date +%Y%m%d%H%M`
but I get the same error still.
I cut down your script to this:
#! /bin/tcsh
if ( -n "`find ./monme -newer ./cache`" ) then
echo hello
endif
This gives the same error. I think the culprit is
-n "`find ./monme -newer ./cache`"
What is -n supposed to do? I think it wants a number, but gets something else...
Update: -n in bash means "length of string is non-zero". In my version of tcsh it is as easy to replace as to use == "" like this:
if (( ! -f "./cache" ) || ("`find ./monme -newer ./cache`" != ""))
then
touch cache -t "$now"
echo "new files added" | mail -s "new build" myemail#myserver.com
endif
Try that and see if it works.