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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

splicing, splitting and joining a field

Status
Not open for further replies.

gogirl

MIS
Jun 5, 2002
46
0
0
US
I am trying to split up a field that contains a client matter number. This number is joined together by a period like this 999999.99999 with 6 numbers to the left of the '.' and 5 to the right. I am trying to:
1. splice the field from an array of strings //field #8
2. split the client/matter#
3. join the client/matter# with a comma
4. pushing it back onto the array

I'm not convinced that this is the best method but I haven't had any luck using a loop with string matching. If you have any suggestions I would really appreciate it.

FYI -- The data is coming out of an ASCII file and being written back to another ASCII file.

Also, what is the simplest way to write out a file?

Here's my code:

use strict;

open(DAT,"newPBX_DATA.TXT") || die("Cannot Open File!");
while (<DAT>)
{
chomp;
my @val = split (/,/, $_, 10000);
$climat = splice(@val, 8, 1);
#remove clientmatter from list and
#store it in $climat
$temp = split(/./, $climat, 50);
$new = join(',', $temp[0], $temp[1]);
push($new);
print join (&quot;,&quot;, @val) . &quot;\n&quot;; # print out.
}
close(DAT);
exit (0);
 
show us what a typical line from newPBC_DATA.txt looks like, where the client/matter number is in the line, and exactly what you want the output to look like.

'hope this helps

If you are new to Tek-Tips, please use descriptive titles, check the FAQs, and beware the evil typo.
 
I liked your breakdown/rebuild idea, and I support it 100%for splitting/joining arrays like you did.
But for string substitions, replacing &quot;in place&quot; is really good.
It was kinda tricky with the period, since is has significance that requires escaping (twice!).
Using your code, I came up with the following answer.
Given a data filename for $dat, the script produces a converted version of the data file, leaving the original data file intact.

Try this:

#Using strict didn't work for me, so I commented it out
#use strict;

$dat = &quot;newPBX_DATA.TXT&quot;; #data filename
$tmp = &quot;tmpPBX_DATA.TXT&quot;; #tmp filename

open(DAT,&quot;< $dat&quot;) || die(&quot;Cannot Open File!&quot;);
open(TMP, &quot;> $tmp&quot;) || die(&quot;Cannot Open File!&quot;);

$period = &quot;\\.&quot;; #for substution, the period (.) has to have \\ before it.
$comma = &quot;,&quot;; #this is for easy substituting like '$climat =~ s/$period/$comma/;'
$intclimat = 8; #this for a number representing the element in the array which contains the client-matter number.
$newline;

while (<DAT>)
{
chomp;
my @val = split (/,/, $_, 10000);

#the line below does period to comma change
@val[$intclimat] =~ s/$period/$comma/; #be sure to get the right element!!

#assign the resulting array to string
$newline = join (&quot;,&quot;, @val) . &quot;\n&quot;;

print TMP $newline; # print out to TMP.
}
close(DAT);
close(TMP);
rename($tmp, &quot;$dat.converted.txt&quot;) or die &quot;can't rename $tmp : $!&quot;;
exit (0);
 
MrGabe,

Your Awesome! Thank you so much for your help. Your use of variables makes the script easier to read and I really appreciate the comments too. I have one other question for you though. After running my script and looking at my text
file, I realized that the quotes were still surrounding the
client matter number like this: &quot;999999,99999&quot;. In order to get it into a mysql database I need to have it look like this: 999999,99999 or &quot;999999&quot;,&quot;99999&quot;. Do you have any
suggestions on how to do this?

I tried substituting the quote(&quot;) with whitespace(/s) but it didn't like that. I've tried a few other things but
they haven't worked.

Thanks Again!
 
I was a sysadmin/database dude at a law firm for a while, and remember having to deal with Client-Matter numbers in our systems, so I can empathize. I didn't know any Perl then and had to make do with Excel/Word/VBA/VB. I think it's great that you're learning Perl to get your work done. There is a learning curve, but anything you learn can really help you out a bunch.

The simplest change is going from &quot;999999.99999&quot; to &quot;999999&quot;,&quot;99999&quot; This is because we can do it with one substition, using the code we already have, and just changing the string value of the $comma variable...

CHANGE: $comma = &quot;,&quot;;
TO: $comma = &quot;\&quot;,\&quot;&quot;; #the \ makes the &quot; literal

Give it a whirl. And good luck to you.

-Gabe
 
Hey Gabe,

I tried that already and it doesn't work. In fact it replaces the whole element with &quot;,&quot;. Got any other tricks up your sleeve?

Cara
 
Cara, this is very mysterious!

hmmm...

It's working without issue on my side with some test data:

Filename= newPBX_DATA.TXT

&quot;jones&quot;, &quot;022550.00001&quot;, &quot;abc&quot;
&quot;smith&quot;, &quot;035700.02000&quot;, &quot;dce&quot;


And here's the script I'm using:
NOTE: I hard code the array element that carries the client Matter number

#use strict;

$dat = &quot;newPBX_DATA.TXT&quot;;
$tmp = &quot;tmpPBX_DATA.TXT&quot;;

open(DAT,&quot;< $dat&quot;) || die(&quot;Cannot Open File!&quot;);
open(TMP, &quot;> $tmp&quot;) || die(&quot;Cannot Open File!&quot;);

$period = &quot;\\.&quot;; #for substitution, the period (.) has to have \\ before it.
$comma = &quot;\&quot;,\&quot;&quot;; #this for easy substituting like '$climat =~ s/$period/$comma/;'
$newline;

while (<DAT>) {
chomp;
my @val = split (/,/, $_, 10000);

#the line below does period to comma change
@val[1] =~ s/$period/$comma/; #be sure to get the right element!!

#assign the resulting array to string
$newline = join (&quot;,&quot;, @val) . &quot;\n&quot;;

print TMP $newline; # print out to TMP.
}
close(DAT);
close(TMP);
rename($tmp, $dat.&quot;conv.txt&quot;) or die &quot;can't rename $tmp: $!&quot;;
exit (0);

If you can't see the problem (difference between yours and mine), post a dummy sample line form your data, and I'll look into it.

-Gabe
 
I had to add a loop to allow for cases where there was no client matter #. I can't see why it would be causing a
problem if I did what you said but for some reason it
didn't work. I tried having two variables one called
$comma1 = &quot;\&quot;,\&quot;&quot;; #with value
$comma2 = &quot;,&quot;; # without value

Here is the code I am using now:

$dat = &quot;newtmpPBX_DATA.TXT&quot;; #data filename
$tmp = &quot;PBX_DATA.TXT&quot;; #tmp filename

open(DAT,&quot;<$dat&quot;) || die(&quot;Cannot Open File!&quot;);
open(TMP,&quot;>$tmp&quot;) || die(&quot;Cannot Open File!&quot;);

$period = &quot;\\.&quot;; #for substitution, the period (.) has to have \\ before it.
$comma = &quot;,&quot;; #this is for easy substituting like '$climat =~ s/$period/$comma/;
$intclimat = 8; #this for a number representing the element in the array
#which contains the client-matter number.
#$newline;

while (<DAT>)
{
chomp;
my @val = split (/,/, $_, 10000); # split, preserving all fields
for my $i (0 .. @val - 1)
{
my $val = $val[$i];
if($val[$intclimat] =~ /\s+\d+\D\d+/)
{
#the line below does period to comma change
$val[$intclimat] =~ s/$period/$comma/;
}
else
{
$val[$intclimat] = $comma,;
}
}

#assign the resulting array to string
$newline = join (&quot;,&quot;, @val) . &quot;\n&quot;; # print out.

print TMP $newline; #print out to tmp

}
close(DAT);
close(TMP);
#rename($tmp, &quot;$dat.converted.txt&quot;) or die(&quot;Can't rename $tmp : $!&quot;);
exit (0);

Here is text after I run this script:

2003-01-07,&quot;18:33&quot;,&quot;00:00:06&quot;, 224, 171,&quot; - - - 0&quot;,&quot;OPERATOR LOC.&quot;, 0.00,,,&quot;OPERATOR LOCAL &quot;,&quot;OUT &quot;
2003-01-07,&quot;18:34&quot;,&quot;00:01:24&quot;, 224, 171,&quot; - -707-8244&quot;,&quot;AUSTIN TX&quot;, 0.00,,,&quot;LOCAL &quot;,&quot;OUT &quot;
2003-01-07,&quot;18:34&quot;,&quot;00:00:42&quot;, 462, 173,&quot; 1-512-542-0087&quot;,&quot;AUSTIN TX&quot;, 0.05,&quot; 013383,00010&quot;,&quot;LD DIRECT DIAL &quot;,&quot;OUT &quot;
2003-01-07,&quot;18:36&quot;,&quot;00:00:12&quot;, 310, 171,&quot; -512-473-0244&quot;,&quot;AUSTIN TX&quot;, 0.00,,,&quot;INCOMING ANI &quot;,&quot;IN &quot;
2003-01-07,&quot;18:37&quot;,&quot;00:12:36&quot;, 573, 173,&quot; 1-915-545-4625&quot;,&quot;EL PASO TX&quot;, 2.35,,,&quot;LD DIRECT DIAL &quot;,&quot;OUT &quot;

Could I do something like this if I placed it before
the substitution?:

$val[$intclimat] =~ ((/d+)(/D)(/d+));
# $1 = client#
# $2 = &quot;,&quot;
# $3 = matter#

$2 = &quot;\&quot;,\&quot;&quot;;

$val[intclimat] =~ sprintf ($1, $2, $3);
 
Cara, thanks for giving me a reason to have the regex lesson. Poof, that was tricky!

I set this up for three cases:
1) you have &quot;&quot; in the data instead of client-matter number
2) you have nothing between the commas for a client matter number
3) you have a client matter number (I did not check for validity, just assuming...)

You get &quot;999999&quot;,&quot;99999&quot; for @val[8]if there is a climat#
You get &quot;&quot;,&quot;&quot; @val[8]if there isn't a climat#, whether it is an empty string or null.

The uniformity of the output should make it easy to import into any database.

here it is:

$dat = &quot;newtmpPBX_DATA.TXT&quot;; #data filename
$tmp = &quot;PBX_DATA.TXT&quot;; #tmp filename

open(DAT,&quot;<$dat&quot;) || die(&quot;Cannot Open File!&quot;);
open(TMP,&quot;>$tmp&quot;) || die(&quot;Cannot Open File!&quot;);

$period = &quot;\\.&quot;; #for substitution, the period (.) has to have \\ before it.

$comma1 = &quot;\&quot;\&quot;,\&quot;\&quot;&quot;; # this creates the empty string vals for 'client' and 'matter' ex:
# changing <data>,,<data> into <data>,&quot;&quot;,&quot;&quot;,<data>

$comma2 = &quot;\&quot;,\&quot;&quot;; #this is for a &quot;,&quot; sequence

$intclimat = 8; #this for a number representing the element in the array
#which contains the client-matter number.
$newline;

while (<DAT>)
{
chomp;
my @val = split (/,/, $_, 10000); # split, preserving all fields
for my $i (0 .. @val - 1)
{
my $val = @val[$i];
if(!$val[$intclimat]=~ /.+/ ) #check for null vals: ...,data,<nothing>,data,...
{
$val[$intclimat] = $comma1;
}
elsif($val[$intclimat]=~ /&quot;&quot;/) # check for empty string: ...,data,&quot;&quot;,data...
{
$val[$intclimat] = $comma1;
}
else
{
#the line below does period to comma change
$val[$intclimat] =~ s/$period/$comma2/;
}
}

#assign the resulting array to string
$newline = join (&quot;,&quot;, @val) . &quot;\n&quot;; # print out.

print TMP $newline; #print out to tmp

}
close(DAT);
close(TMP);
rename($tmp, &quot;$dat.converted.txt&quot;) or die(&quot;Can't rename $tmp : $!&quot;);
exit (0);

try it out. hope it works. My guess is that this is already taking more time than you wanted to spend on it.

Cheers,
-Gabe
 
Hey Gabe,

It worked![thumbsup2] What a fine ending to a Friday! Thanks soooo much for your help. I really do appreciate it.

Best Wishes!!!!

Cara
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top