Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

loop through a string delimited by "|" 1

Status
Not open for further replies.

patnim17

Programmer
Jun 19, 2005
111
US
Hi,
If I have String that is delimited by "|", say

Str="Tom|Andy|Jacob|Sid|Pat" and it can have any number fo fields...

How can a loop though this string a get each name into a variable and display?


pat
 
There are many methods you could use. One example is splitting the string up by termporarily changing a shell's IFS (inter-field separator) and assigning them to an array:

Code:
#!/usr/bin/ksh

Str="Tom|Andy|Jacob|Sid|Pat"

OLDIFS=$IFS
IFS='|'
set -A myarray $Str

i=0
while (( i < ${#myarray[*]} ))
do
        echo ${myarray[$i]}
        (( i=i+1 ))
done
OFS=$OLDIFS

Annihilannic.
 
OK, first, you've asked two programming questions in this forum that really aren't well suited to this forum. Programming forums with lots of talented folks are elsewhere on this site... And now:

If you're going to do a lot of string processing and manipulation, you need to spend some time with perl or PHP. Since you're asking about "how to" on a linux forum, let's do it (your previous post's question and this one) in perl ...

Code:
#!/usr/bin/perl -w

my $st="yxs|yud|abc|def|ghi";
# break down the string using a native command "split"
my @arr = split(/\|/,$st);
# count the array elements using basic perl functionality
my $count=@arr;

print "count: $count\n";

# loop over the array and print it, one item per line
foreach (@arr) {
  print "$_\n";
}

Anni has given you some sweet Awk code, but let's be honest... perl is probably more natural for your tasks.

OK?

D.E.R. Management - IT Project Management Consulting
 
By the way, the one special point in my perl code is this:
Code:
split(/\|/,$st);
Where "/\|/" looks like a lot of leaning sticks...

Normally, when you specify a delimiter for the split command, you can just put it between the slashes..

For example, if you had a comma-delimited file, you would easily use "/,/".

However, because the example uses a "|" character to delimit the string, we have a special case. The "|" char. is a special symbol in perl's parsing logic. To allow it to be used by 'split' we needed to "escape" that character to tell perl to treat it as a string item and not as an operator.

Therefore, "/|/" would not work. But when we "escape" the character by using perl's backslash "\" escaping character, you end up with "/\|/".

You can alternatively give 'split' the matching pattern with quotes rather than slashes but you still must escape the special "|" pipe character.

HTH.


D.E.R. Management - IT Project Management Consulting
 
I tried the script suggested by Annihilannic.

But I get an Error saying set -A Usage is not right..
I could'nt get that code to work...
 
This sounds very much like student homework.

Patnim17:
Why do you want to get each name into a variable and display it?
What language is the rest of your project written in?
What efforts had you already made to solve the problem?
 
Its all Shell Scripting that we are using in Linux Env...I am wondering it that has anything to do with this.

I tried differnt options to get this to work. Here is what my script looks like..and I get the error at line 5 saying: set: -A: invalid option

Str="Tom-Andy-Jacob-Sid-Pat"
echo $Str
OLDIFS=$IFS
IFS='-'
set -A testArray $Str
echo "array size=" ${#testArray[*]}
i=0
while (( i < ${#testArray[*]} ))
do
echo "i=" $i
echo ${testArray[$i]}
(( i=i+1 ))
done
IFS=$OLDIFS
 
Very simple i bash

Code:
#!/bin/bash

OLDIFS=$IFS
IFS='|'

Str="Tom|Andy|Jacob|Sid|Pat"

for i in $Str; do
        echo $i;
done

IFS=$OLDIFS
 
A. Pedant writes:

I'd probably reduce the Perl script to
Perl:
#!/usr/bin/perl
use strict;    # always!
use warnings;  # same as -w on shebang line

my $pipeString = 'yxs|yud|abc|def|ghi'; # (1)
my @names = split(/\|/, $pipeString);   # (2)

print "count: ", scalar @names, "\n";   # (3)

print join("\n", @names);               # (4)
[ol][li]use single quotes around strings that don't need to be interpolated[/li][li]use descriptive variable names, they help when you come to look at the code in six months time[/li][li]the scalar keyword forces the array to be interpreted in a scalar context (which is what happens when you do $x = @y) but saves the pointless creation of a new variable[/li][li]use the join function to print delimited lists from arrays - obviously it still iterates over the array under the covers, so doesn't save any processor cycles, but it's cleaner to write...[/li][/ol]
thedaver said:
this is being made way too difficult by attempting it in shell scripting...
Absolutely right. Shell scripting is the lowest common denominator. Sure, it's guaranteed to be on every system, which is why install scripts and the like are written in shell script. But just because flints and stone tools are available, it doesn't mean we have to use them. You can do anything in Perl that you can do in the shell, but more easily, so if you expect to be doing any amount of scripting, it is well worth taking the time to learn it.

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
A challenge. I like it!
Perl:
print 'Count: ', scalar s/\|/\n/g + 1, "\n", $_ while (<>);
But it reads the pipe-delimited string from standard input. Does that count as cheating?

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top