Stuff
OS/400 Edition
Volume 1, Number 18 -- October 10, 2002

Qshell String Manipulation


by Ted Holt

One might assume that a language that is used primarily for operations and administration tasks would not need string manipulation capabilities. It turns out that string manipulation can come in mighty handy. For example, suppose you wanted to make a backup copy of an Integrated File System (IFS) file to a file of the same name, but with the suffix, whatever it is, changed to the current process ID. You'd need some sort of operator to strip off the suffix.

display

In this article, I give a brief overview of some of the Qshell string-manipulation capabilities. In the examples throughout this article, the commands I typed at the Qshell command line are shown in boldfaced, non-italicized characters. The output of those commands is in normal, italicized characters.

Concatenation

Concatenation is the process of putting strings together to form a longer string. If you look in the Qshell manual, you won't find anything about concatenating strings. Every mention of concatenation refers to files. This might give you the impression that Qshell doesn't have a string-concatenation mechanism, but that's not true. Qshell does not have a string-concatenation operator because it doesn't need one.

I think I can best illustrate this with an example. Let's say there are two variables called firstname and lastname, with the values Josef and Von Schmidt, respectively. Watch this:

hisname=$firstname$lastname
print $hisname
JosefVon Schmidt

How about that! You can jam variables together without a concatenation operator!

The name would look a little better with an intervening blank, don't you think?

hisname="$firstname $lastname"
print $hisname
Josef Von Schmidt

Do you see why I had to add double quotations marks? I need them because of the embedded blank.

Substrings Through Pattern-Matching

To extract a portion of a string, use special forms of parameter expansion. Qshell has four pattern-matching operators and one substring construct. This is the syntax of the pattern-matching operators:


${variable#pattern}

The variable name is followed by an operator; I have used the # operator in the example, but there are three more. The operator is followed by a pattern. The entire expression is enclosed in braces and preceded by a dollar sign.

The following four operators trim characters from the beginning or end of a string.

  • The # operator removes the shortest match from the beginning.
  • The ## operator removes the longest match from the beginning.
  • The % operator removes the shortest match from the end.
  • The %% operator removes the longest match from the end.

It is probably easier to give examples of these operations than to try to explain them.

Suppose a variable called name contained a person's last and first names separated by a comma and a blank space.

print $name
Von Schmidt, Josef

How could you put split the name into two variables?

To get the last name, remove the trailing portion that consists of a comma followed by zero or more characters.

lastname=${name%,*}
print $lastname
Von Schmidt

To get the first name, remove the leading portion that consists of zero or more characters preceded by a comma and a blank space.

firstname=${name#*, }
print $firstname
Josef

I used the % and # operators in these examples, but could have used the %% and ## operators instead, since there was only one comma in the string. Here's another example to illustrate the difference in those operators.

print $ediline
DTP+348+D8+920
print ${ediline%+*}
DTP+348+D8
print ${ediline%%+*}
DTP

The first print shows the present value of ediline, in which elements of a record from a text file are separated by plus (+) signs. The second print removes the shortest pattern that matches a plus sign followed by zero or more characters, which are the last plus sign and the last element of the line.

The third print removes the longest pattern that matches a plus sign followed by zero or more characters, which are the first plus sign and the remainder of the record.

print $ediline
DTP+348+D8+920
print ${ediline#*+}
348+D8+920
print ${ediline##*+}
920

The second print removes the shortest pattern that matches zero or more characters followed by a plus sign, which is everything up to and including the first plus sign. The third print removes the longest pattern that matches zero or more characters followed by a plus sign, which is everything up to and including the last plus sign.

Now you should be able to answer the question I asked in the first paragraph. Suppose you wanted to make a backup copy of an IFS file to a file of the same name, but with the suffix, whatever it is, changed to the current process ID. You'd need to remove the suffix, which is the last period followed by whatever characters there might be, and tack on a period and the $$ special parameter, which returns the ID assigned to the Qshell process.

cp  $filename  ${filename%.*}.$$

If the file name is xyz.csv and the process ID is 9078, the backup copy is xyz.9078.

"But," I hear you say, "what if there is no period in the file name?" In such a case, Qshell cannot match, and therefore cannot remove, any trailing characters. The parameter expansion returns the entire file name. For example, file vvv gets backed up to vvv.9078.

V5R2 Substring Expansion

In OS/400 V5R2, there is one additional parameter-expansion format that extracts substrings. It is similar to the substring functions provided in RPG and CL and the reference modification construct of COBOL.


${variable:offset[:length]}

The offset is the number of bytes from the beginning of the string at which the string extraction should begin. Offsets are numbered beginning with zero, so to extract a substring that begins at the third position of the string, use an offset of 2.

The length is optional. If you specify a length, Qshell extracts that number of characters. If you omit the length, Qshell returns the remainder of the string.

print $name
Von Schmidt, Josef
print ${name:4}
Schmidt, Josef
print ${name:4:2}
Sc

The offset is 4, which tells Qshell to begin extraction with the fifth character of the string.

It's Not an Illusion

My eight-year-old son amazes people by cutting a rope, then putting it back together. It's a trick, of course. He learned it from a book. I hope that what you've learned from this article helps you amaze others as you break apart strings and put them back together in Qshell scripts.


Sponsored By
ASNA

Why Roto-Rooter Uses ASNA Visual RPG for Development:

Roto-Rooter knew that the time had come to replace their green-screen technician dispatch system. When they selected ASNA Visual RPG (AVR) as their development environment, they realized they would be able to use their existing RPG programming skills. They also found that they were able to program even faster than with traditional RPG. Their new AVR application includes capabilities not possible in the green-screen app, such as graphical representations of technician schedules, easy to access menus, and tabs that allow easy movement from screen to screen. These capabilities make their new application much easier for their users to learn and use than the old green-screen version. Since the application now features more information on the screen at one time, in a format that is easier to read, users are able to see and correct scheduling conflicts more quickly than so they can provide a higher level of customer service.

"AVR has saved us so much time while working on our first visual application. I would say that we are able to cut our programming time, just for subfiles, in half and we use subfiles in over 90% of the programs that we have created for this project. It's really nice to be able to move our employees from dumb terminals to PCs and get them using more useful and user friendly applications."
  —Tom Duebber, Roto-Rooter

ASNA Visual RPG (AVR) for Web, Windows and .NET Development

ASNA Visual RPG is a true Windows-hosted RPG compiler. When you select AVR as your programming environment, you are preserving your development team's development skills as well as your shop's long-time investment in RPG. Because AVR is RPG-based, learning curves are amazingly low, even for green-screen veterans who have never written Web or Windows applications before. Couple AVR's easy learning curve with AVR's great documentation and ASNA's superb training classes (offered at ASNA's San Antonio, Texas headquarters and at ASNA's European headquarters in the UK) and your team will be creating problem-solving applications faster than you ever thought possible—and orders of magnitude faster than any competing development tool.

Download your FREE copy of AVR today!

http://www.asna.com/downloads.asp


THIS ISSUE
SPONSORED BY:

T.L. Ashford
Magic Software
LANSA
ASNA
Profound Logic Software
WorksRight Software


BACK ISSUES

TABLE OF CONTENTS
Performing Surgery on the Windows Registry

Back to Basics: Side-by-Side Subfiles

Referential Integrity: Ensuring Your Database Contains Only Valid Data

Qshell String Manipulation

Exploring Data-Type Acronyms

The Client Access Express Toolkit


Editors
Shannon O'Donnell
Kevin Vandever

Managing Editor
Shannon Pastore

Contributing Editors:
Howard Arner
Joe Hertvik
Ted Holt
David Morris
Richard Shaler

Publisher and
Advertising Director:

Jenny Thomas

Contact the Editors
Do you have a gripe, inside dope or an opinion?
Email the editors:
editors@itjungle.com



Last Updated: 10/10/02
Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.