Use grep to Search IBM i Source Members (RPG, CL, COBOL, more)
From the Seiden SmartSupport mailbag:
One issue I keep coming across is the inability to search for text in source members across all libraries. We use a commercial tool, but it is expensive and cumbersome. Coming from the Linux world, where I can “grep” for anything, I find this a ridiculous restriction.
You can, indeed, search source members for text using grep.
December 2024 Update
Try our improved “Physical File Grep (PFGREP)” command instead of the commands below. It is faster and more reliable than QShell grep for searching source code. A more detailed article is on the way.
Original version of the article follows:
Use the correct grep command
To search source members, it’s important to use Qshell’s version of grep, which understands native EBCDIC encoding. In other words, instead of the standard PASE version (/QOpensys/pkgs/bin/grep
), use /usr/bin/grep
instead.
How to grep for text
Let’s say you want to find out where RPG calls PHP. Grep can search for the string “php” (case-insensitive) inside RPG source members.
From QShell (called from a traditional 5250 IBM i command line):
QSH
Then search for our desired text (“php” in our case) using grep:
/usr/bin/grep -i -n "php" /QSYS.LIB/*.LIB/QRPG*.FILE/*.MBR
From Bash shell
If you are in a bash shell, rather than Qshell, you need a slightly more complex command so that Qshell still processes the output. The command from bash should look like this:
echo "/usr/bin/grep -i -n "php" /QSYS.LIB/*.LIB/QRPG*.FILE/*.MBR" | qsh
With our server, here are some of the results:
1 2 3 4 5 6 7 8 |
/QSYS.LIB/GBA.LIB/QRPGLESRC.FILE/VVADM_PHPS.MBR:6: ** Object ID: VVADM_PHPS /QSYS.LIB/GBA.LIB/QRPGLESRC.FILE/VVADM_PHPS.MBR:8: ** Description: Valence PHP Settings Maintenance /QSYS.LIB/GBA.LIB/QRPGLESRC.FILE/VVADM_PHPS.MBR:22: d getPhpDirectives... /QSYS.LIB/GBA.LIB/QRPGLESRC.FILE/VVADM_PHPS.MBR:24: d savePhpDirectives... /QSYS.LIB/GBA.LIB/QRPGLESRC.FILE/VVADM_PHPS.MBR:27: d getPhpDirPos pr /QSYS.LIB/XMLSERVILE.LIB/QRPGLESRC.FILE/PLUGIPC_H.MBR:141: * example (php sudo): /QSYS.LIB/XMLSERVILE.LIB/QRPGLESRC.FILE/PLUGIPC_H.MBR:284: * - *log key is unique allowing both PHP and XMLSERVICE /QSYS.LIB/XMLSERVILE.LIB/QRPGLESRC.FILE/PLUGXML_H.MBR:109: * -> PHP client bin2hex('wild_ascii_raw_chars') |
Each search result above includes:
- Full path to the source member
- Line number where the string was found
- The line itself. Because we used grep’s
-i
option, the results were case insensitive; that is, PHP, Php, and php all matched.
Thanks to Liam Allan for his assistance with this tip.
January 2024 Update
Since the original 2023 publication of this post, both Simon Hutchinson and Richard Schoen have published code to run grep source code searches from traditional ILE and 5250 environments. We thank them for their work and recommend people check it out:
- Simon Hutchinson’s Using QShell to Search Source Members includes instructions for sending the data to an IBM i output file as well as other refinements.
- Richard Schoen created a new CL command and made it freely available via GREPSRCLIB CL Command – Search Library Source Members using Grep. Copy and compile the source code of any of his sample CL commands to use as you see fit.
It’s very interesting. However I have some problems: The example, as it is, does not work in V7R4 but in general it does the job. In V7R5 it works perfectly (as indicated in the article)
Hi, Nelson, thanks for your comment. We’ve successfully tested this technique on an IBM i 7.4 system, so I don’t think the OS level is the problem. Let us know if you can identify some other difference.
I have little experience in using QSH how would you write the output to an *OUTFILE on your IBM i?
Steve,
you can try to use the “ifs” syntax :
system “dspsavf qgpl/mysavf output(*print)” >> /QSYS.LIB/MYLIB.LIB/MYFLE.FILE/MYMBR.MBR 2>&1
Reference:
https://www.ibm.com/support/pages/redirecting-output-qshell
&
https://www.seidengroup.com/2021/02/25/reading-and-writing-physical-files-in-a-shell-using-rfile/
We plan to update the article with instructions on writing the output to an IFS file. We think it should be possible to use RFile to write to a physical file (table) as well but will see.
F6 to a spool file and go from there?
Looks really great but I get nothing. I’ve tried it both ways. :-(
Likewise
I was getting nothing either until I change the syntax to include a specific library name:
/usr/bin/grep -i -n “searchword” /QSYS.LIB/LIBRARYNAME.LIB/QSQLSRC.FILE/*.MBR