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

Find/replace awk problem

Status
Not open for further replies.

kat000003

Technical User
Jan 27, 2005
37
CH
I have 2 files (A + B) as below.
I want to replace string "BNo" in file A with the byte position in file B where the string appears.
I can do it using various steps but it takes too long and my files are 46Mb in size.Is there a simple way ?
File A
111,BNo,"A lot of stuff"
222,BNo,"A lot of stuff"
333,BNo,"A lot of stuff"

File B
"Stuff",444,"Stuff"
"Stuff",111,"Stuff"
"Stuff",999,"Stuff"

Result
111,27,"A lot of stuff"
222,0,"A lot of stuff"
333,0,"A lot of stuff"
 
Code:
[b]#!/usr/bin/perl[/b]

open (FILE_A, "< file_A.txt");
chomp (@file_A = <FILE_A>);
close FILE_A;

open (FILE_B, "< file_B.txt");
undef $/;
$file_B = <FILE_B>;
$/ = "\n";
close FILE_B;

foreach $a_line (@file_A) {
  
  # retrieve just the number...
  $a_line =~ m/^([^,]+).*$/;
  $a_number = $1;
  
  # find its position in file B...
  $file_B =~ m/(.*,)$a_number,/s;
  $located = $1;
  $position = length $located;
  
  # search & replace...
  if ($1 eq $a_number) {
    $a_line =~ s/^([^,]+),BNo,(.*)$/$1,0,$2/;
  } else {
    $a_line =~ s/^([^,]+),BNo,(.*)$/$1,$position,$2/;
  }
  
  print "$a_line\n";
  
}


Kind Regards
Duncan
 
Code:
BEGIN { FS = OFS = "," }
NR==FNR { data = data $0 ; next }
{ $2 = index( data, $1 ) ; print }
Save this code to file BNo.awk and run with
[tt]awk -f BNo.awk fileB fileA >newfileA[/tt]
Note that fileB comes before fileA.

In your example, I think that

Result
111,27,"A lot of stuff"

should be

Result
111,28,"A lot of stuff
 
I was going to suggest you post this in the awk forum - and futurelet has shown why!

3-lines of script ... nice!

And I also have to agree with futurelet on the count of 28 - my script returns the same


Kind Regards
Duncan
 
My code will produce wrong results under some circumstances. Say you have these 2 files:

File A
111,BNo,"A lot of stuff"
222,BNo,"A lot of stuff"
333,BNo,"A lot of stuff"
44,BNo,"A lot of stuff"

File B
"Stuff",444,"Stuff"
"Stuff",111,"Stuff"
"Stuff",999,"Stuff"
"Stuff",44,"Stuff"

The "44" in line 4 of File A will be found in line 1 of File B instead of in line 4. This should fix it.
Code:
BEGIN { FS = OFS = "," }

# Reading first file?
FILENAME==ARGV[1] { data = data $0 ; next }

{ $2 = index( data, FS $1 FS )
  if ( $2 ) $2++
  print }
 
I do not have perl.
How do I do this using command line AWK ?
 
Paste the code into a text editor and save to file [tt]BNo.awk [/tt] and run with
[tt]
awk -f BNo.awk fileB fileA >newfileA
[/tt]
Note that fileB comes before fileA.
 
Thanks guys but I still am hitting problems.
If my 2nd file has the search string anywhere in the record, it is finding it.
I need it to only look at column 1 (ie if I was searching for 44, the result should be 77).
My fileB actually looks like this ;
444,"Stuff",123,"Stuff2"
111,"Stuff",44,"Stuff2"
999,"Stuff",56111,"Stuff2"
44,"Stuff",100,"Stuff2
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top