1828038 Members
1979 Online
109973 Solutions
New Discussion

Re: script help

 
SOLVED
Go to solution
Chris H_3
Advisor

script help

Hi all,

I use a script that does some clean up when users are removed from the system, and sends an email to various people with info. Now we have a bunch of single column lists that these usernames might be in also. I'm looking for a way to remove the names from those lists also, automagically!

I can find the files the name is in with:
find /dir/*.txt -exec grep -l 'username' {} \;

but can't think of a way to chain that with the removal of the username. I thought of piping that through a "grep -v 'username' > something" and overwriting the same files so I don't have to do a 'mv filename.tmp filename', etc, but just can't get it.

It of course doesn't have to be one line, but that's more challanging. :)

Thanks for any assistance!

CH
5 REPLIES 5
Stuart Browne
Honored Contributor

Re: script help

Sed:

sed -ne '/[^username]/p' < file > file.new && mv file.new file

Awk:

awk '!/^username$/' < file > file.new && mv file.new file

One long-haired git at your service...
Steven E. Protter
Exalted Contributor

Re: script help

You could pipe your output into rm.

I rarely do that, because there is no recycle bin in Linux.

I redirect the find to a file and:

while read -r filename
do
mv $filename $filename.dat
done < input filelist



Thats a good script device and follow on.

SEP
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com
Muthukumar_5
Honored Contributor

Re: script help

you can change the result file with out using temporary file or mv command as like,

--- test file ---
user1
bye for now
----------------

echo `sed -e '/^user1/!d' testfile` >testfile

To simultaneously do it,

find $PWD/* -exec grep -l 'user1' {} \; | awk '{ print "echo `sed -e '/[^user1$]/\!d' "$1"` > "$1 }' | sh

It will change the contents of every file listed out there without user1 in that

Use user1 without username.

Easy to suggest when don't know about the problem!
Hein van den Heuvel
Honored Contributor
Solution

Re: script help

Here is an addaption of a perl script I used for similar jobs.

It assumes data in the Megabyte range, not Gigabytes as it sucks up the files.
Should be close to your needs.
Only changes the files that need changing.
Only reads the files once.
Renames to old files away, just in case.

$test = shift @ARGV;
die "Must provide line to look for" unless $test;
$dir = shift @ARGV;
foreach $file (<${dir}*.txt>) {
$files++;
open (F, "< $file");
while () {
if (/^$test$/) {
$need_new = 1;
$changes++;
} else {
push @lines, $_;
}
}
close (F);
if ($need_new) {
$need_new = 0;
rename $file, $file . ".old";
open (F, "> $file") or die "Can not create new file $file";
foreach (@lines) { print F $_ };
close (F);
undef @lines;
}
}
print "$changes lines removed from $files files.\n";
Chris H_3
Advisor

Re: script help

Thanks all for the great tips, sorry it took so long to get back to this, had to quell some fires.

I was able to implement Hein's solution without issue, and is working as intended. I also liked Muthukumar's, what I was initially looking for, but for some reason I couldn't get my username var to pass into the sed portion. Works great on the command line, but not in my script. Have to play with it more and figure it out, but it's a great one liner!

Thanks all!

CH