25 pts.
 How to parse a file for a specific pattern?
Hello!
i'm new to AS400, and I've been trying to figure out for the whole day how to have the similar behavior as the following unix command:
grep "pattern" my_file
exit $?
1) Grep a pattern in a log file
2) exit OK (or echo OKmessage) if the pattern is found, 
    exit NOT OK or echo NOT OK message if not found
I can grep using:
CALL PGM(QSHELL/GREP) PARM('Operation Successful' '/PMGT/TMPLIB/jyfile.txt')
But how can I get a return code or status?
Thanks!!


Software/Hardware used:
AS400
ASKED: October 27, 2009  12:34 PM
UPDATED: November 5, 2009  6:08 PM

Answer Wiki:
I'm not sure how you would do this in UNIX, but this is how I would do it with RPGLE: <pre> D POS S 5 0 INZ(0) // ************************************************************* // * CHECK ITEM APPLICATION FOR AMPERSAND. // ************************************************************* RESET POS; RESET PASS_DESC; POS = %SCAN('&' : pData); IF POS <> 0; PASS_DESC = %TRIM(pData); pData = %TRIM(AMPERSANDR(PASS_DESC : POS)); ENDIF; </pre> The problem with %scan is that it will only return the first occurrence of the pattern. If you need to find all occurrences’ of the pattern, you will need to contain the above example in a loop. ______________________________________________________________________ It looks like I am missing the first part of my post after the code segment. It should say: %scan will search the string, in this case pData for the pattern specified in the first part of the command, the '&'. If it finds one then POS will be updated with the position where the pattern was found. For example, if pData contained "Sanford & Son" then POS would equal 9. If pData contained "Sanford and Son" then POS would equal zero. The problem with %scan is that it will only return the first occurrence of the pattern. If you need to find all occurrences’ of the pattern, you will need to contain the above example in a loop. ========================================================= Although many Qshell programs can be called directly, it isn't how things should normally be done. Qshell programs will usually assume that they're running inside of the shell. The shell provides environment facilities that may be important. Redirection, file handles, etc., ought to be attended to by the shell. Rather than issuing a CALL, use the STRQSH command to invoke a Qshell function. In your case, this will probably be invoking a Qshell script that you've written. But in it's simplest form: <pre> STRQSH CMD( 'grep "pattern" my_file' ) </pre> Qshell commands entered with STRQSH may be single commands or separated by semi-colons. However, you probably are needing to write a script and store it in an IFS directory, and then: <pre> STRQSH CMD( 'mypath/myscript.sh' ) </pre> ...to run the myscript.sh script. To investigate Qshell, simply run STRQSH with no command parameter. You will be taken into the interactive Qshell. Tom
Last Wiki Answer Submitted:  October 27, 2009  11:52 pm  by  Teandy   5,830 pts.
All Answer Wiki Contributors:  Teandy   5,830 pts. , TomLiotta   108,310 pts.
To see all answers submitted to the Answer Wiki: View Answer History.


Discuss This Question:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _


 

Hey Tom!
Thanks for your answer, it’s a big help.
Your last command STRQSH CMD( ‘grep “pattern” my_file’ ) would be quite good.

The only thing I need now is to define the status.

I’d like to have a CLP program doing:
STRQSH CMD( ‘grep “pattern” my_file’ )
IF (pattern found) THEN DO ACTION_OK
ELSE DO ACTION NOT_OK
END
Do you think it’s possible to pass a value from the qsh execution to the CLP?

If I use STRQSH I can get the return code of the command:
cp tutu tut cp: 001-2113 Error found getting information for object tutu. No such path or directory $
> echo $?
1 => 1 means NOT OK
ls BYPASS.SAVF src.data f00063.tmp
> echo $?
0 => 0 means OK

Thanks again

 25 pts.

 

Given my lack of time, I’ll point this out for now — V5R4 Qshell basic docs.

Without knowing something about what you need to do in [DO ACTION_OK/NOT_OK], I can’t suggest the better course. It’s possible you simply want the action to be done inside Qshell before dropping back out of the shell.

More time later tomorrow.

Tom

 108,310 pts.

 

Here is the final code that works!

QSH to grep and then check the msg.

Thanks for your help and hope this can help smbdy :)

/* ---------------------------------------------------------------  */
/*  LOG PARSING                                                     */
/* ---------------------------------------------------------------  */
 /* IF VARIABLES WERE SET PREVIOUSLY, REMOVE THEM SO THAT OUR +
    ADDENVVAR COMMANDS WORK.                                  */
STEPLP:
       RMVENVVAR  ENVVAR(QIBM_QSH_CMD_OUTPUT)
       MONMSG MSGID(CPFA981) /* ENVVAR DOES NOT EXIST */

       RMVENVVAR  ENVVAR(QIBM_QSH_CMD_ESCAPE_MSG)
       MONMSG MSGID(CPFA981) /* ENVVAR DOES NOT EXIST */
 /* SET THE COMMAND OUTPUT TO NONE, AND TELL QSH TO ISSUE +
    ESCAPE MESSAGES FOR ERRORS.                               */

       ADDENVVAR  ENVVAR(QIBM_QSH_CMD_OUTPUT) VALUE(NONE)
       ADDENVVAR  ENVVAR(QIBM_QSH_CMD_ESCAPE_MSG) VALUE(Y)
 
 /* EXECUTE OUR QSHELL COMMAND */
             CHGVAR     VAR(&GREP_CMD) VALUE('grep -i "' +
                          *TCAT &GREP_MSG *TCAT '"  ' *CAT &LOGFILE)
  /*           CALL       PGM(UXSET) PARM('msg' &GREP_CMD) */
       STRQSH CMD(&GREP_CMD)
/* HANDLE ERRORS. */

       MONMSG MSGID(QSH0005 QSH0006 QSH0007) EXEC(DO)

            RCVMSG  MSGTYPE(*LAST) RMV(*YES) MSGDTA(&MSGDTA) +
                      MSGID(&MSGID)

          /* CPF0005 - QSHELL COMMAND ENDED "NORMALLY."         */

            IF (&MSGID *EQ 'QSH0005') DO
                CHGVAR VAR(&RESULT) VALUE(%SST(&MSGDTA 1 4))
                CHGVAR VAR(&STATUS) VALUE(%BIN(&RESULT))
                CHGVAR VAR(&SIGNAL) VALUE(0)
            ENDDO

          /* QSH0006 - QSHELL COMMAND ENDED WHEN IT RECEIVED A  +
                SIGNAL.                                         */

            IF (&MSGID *EQ 'QSH0006') DO
                CHGVAR VAR(&RESULT) VALUE(%SST(&MSGDTA 1 4))
                CHGVAR VAR(&SIGNAL) VALUE(%BIN(&RESULT))
                CHGVAR VAR(&STATUS) VALUE(-1)
            ENDDO

          /* QSH0007 - QSHELL COMMAND ENDED DUE TO AN EXCEPTION,  +
               FOR EXAMPLE THE PROGRAM CRASHED WITH A CPF MSG.   */

            IF (&MSGID *EQ 'QSH0007') DO
                CHGVAR VAR(&STATUS) VALUE(-1)
                CHGVAR VAR(&SIGNAL) VALUE(-1)
            ENDDO
       ENDDO

       /* WHEN &STATUS IS NOT ZERO, WE KNOW OUR GREP COMMAND.    +
          FAILED: KEYWORD WAS NOT FOUND.          */
/* DISPLAY MESSAGE */

       IF (&STATUS *EQ 0) THEN(DO)
            CHGVAR VAR(&MSGTXT) VALUE('Enhanced Status Management: "' +
                      *TCAT &GREP_MSG *TCAT '" found in ' +
                      *CAT &LOGFILE *TCAT ' ')                            
       ENDDO
       IF (&STATUS *NE 0) THEN(DO)
            CHGVAR VAR(&MSGTXT) VALUE('Enhanced Status Management: "' +
                      *TCAT &GREP_MSG *TCAT '" not found in ' +
                      *CAT &LOGFILE *TCAT ' ')
       ENDDO
 25 pts.

 

In biterscripting

var str file ; set $file=”C:/file.txt”
var str pattern ; set $pattern = “abc”
var str content ; cat $file > $content
if ( { sen (“^”+$pattern+”^”) $content } > 0 )
echo “PATTERN IS PRESENT.”
else
echo “PATTERN IS NOT PRESENT.”
endif

The help page for the sen (string enumerator) command is at http://www.biterscripting.com .

 70 pts.