LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 07-31-2003, 11:00 PM   #1
ckibler
LQ Newbie
 
Registered: Jul 2003
Location: Illinois
Posts: 1

Rep: Reputation: 0
Unhappy grep - finding string and replacing with new


OK, I am a windows guy emersed into Unix and Linux and trying not to drown.

I have read the man pages on grep, I have read every thread here on grep - still I have questions.

1) I have transferred accounts and files from True-64 Unix box to Red Hat 8 so I have to search all the .cgi files and replace a two things:
a) phrase of /usr/users with /usr/local/users in each .cgi
b) the home of the exec of perl

2) I have done a "find ./ -name *.cgi > kib.txt" so I have a list of all the cgi files on the box.

Now how do I write the grep to find the files that contain /usr/users within them in the separate sub-directories.

I can do it in the directory itself by grep /usr/users *.cgi

How do I get grep to look into all the subdirectories of /usr/local/users for all the .cgi files that contain /usr/users

3) Once I have this list of the actual files - How do I remove and replace /usr/users with /usr/local/users in each file?

I know - It is a lot to ask! Thanks in advance. Been scratching my head a lot tonight without a lot of progress, so any help will be greatly appreciated.

Chuck K.
 
Old 08-01-2003, 12:08 AM   #2
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
To make grep look in subdirectories you do
grep -r /usr/users /usr/local/users/*.cgi
(which will only owrk out right if there's
actually a file of that type in the top level
directory of your search)...


As for the replace ... I'm afraid that won't be
possible without a shell-script :}

I'd recommend to look at sed or awk as the
tools for the search and replace.

Cheers,
Tink
 
Old 08-01-2003, 03:58 PM   #3
elam
LQ Newbie
 
Registered: Aug 2003
Posts: 21

Rep: Reputation: 15
I would use Perl.


#!/usr/bin/perl

use strict;
my $filename = pop @ARGV;
chomp $filename;

# Open file name list and open each file in the list.
open LIST, "$filename";
foreach my $file( <LIST> ) {

my @temp;
open FILE, "$file";

foreach my $line( <FILE> ) {
push @temp, $line; # Put all lines in an array.
}

close FILE;
open REPLACE, ">$file"; # open file for writing.
select REPLACE; # redirect output to file.

foreach my $line( @temp) {
$line =~ s/usr\/users/usr\/local\/users/g; # Substitute and print each line to file.
print "$line";
}

close REPLACE;
}

close FILE;
select STDOUT;

Copy and paste and save as 'filename'. You can execute with:
'perl filename /path/to/kib.txt'

You need to have permissions for the appropriate directories to work

Last edited by elam; 08-01-2003 at 04:00 PM.
 
Old 08-01-2003, 05:12 PM   #4
Bebo
Member
 
Registered: Jul 2003
Location: Göteborg
Distribution: Arch Linux (current)
Posts: 553

Rep: Reputation: 30
Hmm, isn't perl a bit of overkill? To get the files that contain a certain searchstring I would use something like

grep -rc <searchstring> <where to search> | grep -v :0

The c flag in the grep command counts the occurences of the searchstring in every file, so to only get the files that actually contains the searchstring, I would have to make an inverse grep on :0 to filter out the interesting files.

Now, if we wanted to get the "pure" file name, we have to get rid of the trailing ":<number>" that every hit has. I would perhaps do it like this:

grep -rc <searchstring> <where to search> | grep -v :0 | tr \: '\t' | cut -f1

It seems a bit cumbersome but that's the best I could come up with now

To change a string to something else I would use sed, like this:

cat oldfile | sed s/<searchstring>/<replacement>/g > newfile

I don't think that the new and old files can be the same one. I've tried that and that was REALLY bad

So, in your case a script would look something like this

Code:
#!/bin/bash

for file in `grep -rc \/usr\/users  /usr/local/users/*.cgi  | grep -v :0 | tr \: '\t' | cut -f1` ; do
   cat $file | sed s/'\/usr\/users'/'\/usr\/local\/users'/g > $file.new
done
I hope I got all the backslashes in the right places Of course, with this script, you'd have to copy all the .cgi.new files to the proper .cgi file. This can of course be avoided by just adding the line

cp $file.new $file

in the loop after the replacement line. However, in this way you can check that it works properly first, and that it doesn't eat all you files.
 
Old 08-01-2003, 05:28 PM   #5
elam
LQ Newbie
 
Registered: Aug 2003
Posts: 21

Rep: Reputation: 15
Quote:
grep -rc <searchstring> <where to search> | grep -v :0

The c flag in the grep command counts the occurences of the searchstring in every file, so to only get the files that actually contains the searchstring, I would have to make an inverse grep on :0 to filter out the interesting files.
Just curious, why not just replace with 'grep -rHl <searchstring> <where to search>' ?
 
Old 08-01-2003, 06:09 PM   #6
Bebo
Member
 
Registered: Jul 2003
Location: Göteborg
Distribution: Arch Linux (current)
Posts: 553

Rep: Reputation: 30
Hm, let's try...

*testing*

Well, you'll only get the matching files as output, which is good. However, if more than one line matches in your file, you'll get one line of grep output PER MATCH, which is not what you wanted, right? Furthermore, you'll also get the grep:ed line(s) as output! Of course you could remove this part and only use the filename, but that would be just as much work as in my script. I think
 
Old 08-01-2003, 07:25 PM   #7
elam
LQ Newbie
 
Registered: Aug 2003
Posts: 21

Rep: Reputation: 15
O.k. I get it now...

Last edited by elam; 08-01-2003 at 07:34 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
c++ : replacing a char in a string cb951303 Programming 20 02-25-2015 09:18 PM
use grep and execute a command if string is found plisken Linux - General 6 07-28-2005 12:06 PM
Exercise 1-9. Write a program to copy its input to its output, replacing each string zombi3 Programming 3 12-21-2003 03:28 AM
how to grep only one string pr match gummimann Linux - General 3 11-06-2003 10:40 AM
Replacing String with File Content in Sed meshcurrent Linux - General 2 06-01-2003 01:54 AM


All times are GMT -5. The time now is 01:43 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration