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

Nawk to Replace Text 2

Status
Not open for further replies.

beaster

Technical User
Aug 20, 2001
225
US
I have multiple files named beaster#, which contain a line in them like :

@SET LOGFILE=("/home/bham_mta/rehome_scripts/cmd_file1")

I want to replace the text "cmd_file1" with file#

File# being the numeric digit from the name of this file "beaster1". So the text would end up file1, and the next file2, file3, and so on.

Since I never know how many beaster files there will be, it would need to loop until it has gone through all the files that may be in the directory that are labeled beaster#

Like:
beaster1
beaster2
beaster3
beaster4

would all have the text "cmd_file1" changed to:

@SET LOGFILE=("/home/bham_mta/rehome_scripts/file1")

@SET LOGFILE=("/home/bham_mta/rehome_scripts/file2")

@SET LOGFILE=("/home/bham_mta/rehome_scripts/file3")

@SET LOGFILE=("/home/bham_mta/rehome_scripts/file4")

I hope this hasn't been confusing.

Thanks as always,
Beaster

 
Hi beaster,

Try this.
[tt]
{
if ($0 ~ /@SET LOGFILE/) {
n1 = substr(FILENAME,length(FILENAME),1)
sub(/cmd_file1/,"file" n1)
}
print
}
[/tt] CaKiwi
 
Thanks CaKiwi,

Should I put this in a file, and run nawk from the script like :

nawk -f nawk_file ?

I did not see above where the beaster files will be called from?? I may have numerous ones of those....
 
Sorry, also the files will have more than just the text below in them:

@SET LOGFILE=("/home/bham_mta/rehome_scripts/cmd_file1")


I saw above where $0 was looking for
($0 ~ /@SET LOGFILE
 
You will need for run it for each beaster file.

nawk -f nawk_file beaster1 > new_beaster1

You can use a loop in a shell script. Someone else can probably give you the exact syntax faster than I can figure it out. What shell are you using?

Change the /@SET LOGFILE/ if necessary so you only find the lines you need to change. CaKiwi
 

something to start with:

nawk -f beast.awk beaster*

#----------- beast.awk ----------

BEGIN {
pattern="^@SET LOGFILE=";

}

$0 ~ pattern {

filenum=substr(FILENAME, match(FILENAME, "[0-9]+"));
# printf("filenum->[%s]\n", filenum);

arrNum=split($0, arr, "\"");
# printf("arr2->[%s]\n", arr[2]);
numPath=split(arr[2], path, "\/");
# printf("leaf->[%s]\n", path[numPath]);
path[numPath]="file" filenum;
# printf("NEWleaf->[%s]\n", path[numPath]);

printf("%s\"", arr[1]);
for (i=1; i <= numPath; i++)
printf(&quot;%s&quot;,(i == 1) ? path : &quot;/&quot; path);
printf(&quot;\&quot;%s\n&quot;, arr[3]);

}

vlad
+---------------------------+
|#include<disclaimer.h> |
+---------------------------+
 
Thanks vgersh99, But that is way over my head...I was looking for something a bit simpler....
 
Ok maybe it wasn't to much over my head, it did what I wanted it to perfectly, except how do I get it to write it back to the same filename? It output to the screen:

nawk -f nawk_firstfile beaster*
@SET LOGFILE=(&quot;/home/bham_mta/rehome_scripts/file1&quot;)
@SET LOGFILE=(&quot;/home/bham_mta/rehome_scripts/file2&quot;)
@SET LOGFILE=(&quot;/home/bham_mta/rehome_scripts/file3&quot;)
 
you can't with awk. You'll have to save it a temp. file and then 'mv' the temp file into the original [as suggested by CaKiwi].

If you want to modify the original file without the 'mv', you'd have to use ed, ex [with the sed-like expressions]. vlad
+---------------------------+
|#include<disclaimer.h> |
+---------------------------+
 
I think ths may do what you want. Create a sub directory new then run

nawk -f nawk_file beaster*

{
if (FNR == 1) fn = &quot;new/&quot; FILENAME
if ($0 ~ /@SET LOGFILE/) {
n1 = substr(FILENAME, match(FILENAME, &quot;[0-9]+&quot;))
sub(/cmd_file1/,&quot;file&quot; n1)
}
print > fn
}

I fixed a problem setting the file number n1 so that it would work with more than 1 digit. OK, I admit it, I just copied the line from Vlad's script. CaKiwi
 
Ok now that is SWEEEEEETTTTT!!!!

It works perfect! Both you guys are awesome thanks!!!!

Beaster
 
Guys at the end can I make it write this also?

echo &quot;/opt/tmos/bin/ops_nui -file /home/bham_mta/rehome_scripts/beaster1 (or whatever the # was) >> rehome.txt

Thanks,
Beaster
 
nawk -f nawk_file beaster*

{
if (FNR == 1) fn = &quot;new/&quot; FILENAME
if ($0 ~ /@SET LOGFILE/) {
n1 = substr(FILENAME, match(FILENAME, &quot;[0-9]+&quot;))
sub(/cmd_file1/,&quot;file&quot; n1)
printf(&quot;/opt/tmos/bin/ops_nui -file /home/bham_mta/rehome_scripts/beaster%d\n&quot;, n1) >> rehome.txt
}
print > fn

} vlad
+---------------------------+
|#include<disclaimer.h> |
+---------------------------+
 
CaKiwi,
I had to come back to your awk script here:

nawk -f nawk_file beaster*

{
if (FNR == 1) fn = &quot;new/&quot; FILENAME
if ($0 ~ /@SET LOGFILE/) {
n1 = substr(FILENAME, match(FILENAME, &quot;[0-9]+&quot;))
sub(/cmd_file1/,&quot;file&quot; n1)
}
print > fn
}


I didn't know I would have more than 27 files and it bombs on number 28 real hard:

nawk -f nawk2 beaster*
nawk: temps/beaster28 makes too many open files
input record number 1, file beaster28
source line number 9

Is there a modification that can be made so it run up to maybe 100 files or more. I cant have it bomb at 28 or any number in fact????

Thanks,
Beaster
 
Try changing

if (FNR == 1) fn = &quot;new/&quot; FILENAME

to

if (FNR == 1) {
if (fn) close(fn)
fn = &quot;new/&quot; FILENAME
} CaKiwi
 
It's very rare to see Cakiwi not call close().
That's probably the problem.

try:
<snip>
print > fn
close(fn)
}
 
Thanks they both worked. I am just going through the entire script line by line before I have to run it live three nights next week

I may have some quick fixes I need help with if that is ok. I have only been running it the last few months on 3 cell sites, now I have to get ready for at least 100.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top