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!

passwd file comparison 1

Status
Not open for further replies.

sawtooth

Technical User
Aug 22, 2001
2
CA
Hi, I'm not really a programmer, but I have this admin problem to solve and I've worked at it for days without success.

What I want to do is read the /etc/passwd file and compare it to another file which contains new users to add to the /etc/passwd file. However I don't want to add a user who is already there. The output of both these files will be a new and updated /etc/passwd file.
The other thing I need to do is to remove certain users by reading a third file that contains the user name only.

I hope this makes sense. Anybody?

Thanks
 
The first by:

#!/bin/sh
function p_names() {
echo -e "` awk ' {
while ((getline names < &quot;/etc/passwd&quot;) > 0) {
split(names , user_names, RS)
chek = $0
for (x in user_names)
if (user_names[x] ~ chek) {
print &quot;User dupe at:&quot; , $0
}
}
}'`&quot; | sort -u


The second by:

echo -n &quot;Comparefile: &quot;
read cfile

for x in `cat cfile`
do
echo $x | sift
done


Then for the third:

for bads in `cat thirdfile`
do

awk -v i=$bads {
gsub(i, &quot;&quot;, $0)
print > newfile
}' /etc/passwd
done

or with sed:

sed &quot;s/$bads//g' /etc/passwd > newfile

Good Luck, hope this helps.

 
Oops, rename the shell function p_name
to sift I was testing two different scripts
with the same function code/different function names..brain death.

Procedure:
First you program the filter in a shell function through awk-the first part.

Secondly you loop through a file containing user names to compare to the /etc/passwd
file, generating dupe users and creating
a newfile. echo $x | sift > newfile


Then you take your third file and loop
through it using either awk or sed to
replace names and create your final
product-> which you then have to test
as the new /etc/passwd and integrate if
you are using shadow passwords...


A challenge would be to do this totally in awk...I think it could be done...
 
Here is a pure awk solution for the first task...

BEGIN{
FS=&quot;:&quot;
n = 0
while ((getline < &quot;/etc/passwd&quot;) > 0) {
pw0[n] = $0
pw1[n] = $1
n++
}
j = n
}
{
for (i=0;i<n;i++) {
if ($1 == pw1) break
}
if (i==n) {
pw0[j] = $0
j++
}
}
END {
for (i=0;i<j;i++) print pw0
}

and for the second task.

BEGIN{
FS=&quot;:&quot;
n = 0
while ((getline < &quot;/etc/passwd&quot;) > 0) {
pw0[n] = $0
pw1[n] = $1
n++
}
}
{
for (i=0;i<n;i++) {
if ($1 == pw1) break
}
if (i<n) {
del = 1
}
}
END {
for (i=0;i<n;i++)if (!del) print pw0
}

Hope this helps. CaKiwi

After all is said and done, a lot more will have been said than done.
 
I just noticed that &quot;square braket i close square bracket&quot; turn on italics and gets dropped from the post. I changed i to k and here they are again.

----------------

BEGIN{
FS=&quot;:&quot;
n = 0
while ((getline < &quot;/etc/passwd&quot;) > 0) {
pw0[n] = $0
pw1[n] = $1
n++
}
j = n
}
{
for (k=0;k<n;k++) {
if ($1 == pw1[k]) break
}
if (k==n) {
pw0[j] = $0
j++
}
}
END {
for (k=0;k<j;k++) print pw0[k]
}

-------------------------

BEGIN{
FS=&quot;:&quot;
n = 0
while ((getline < &quot;/etc/passwd&quot;) > 0) {
pw0[n] = $0
pw1[n] = $1
n++
}
}
{
for (k=0;k<n;k++) {
if ($1 == pw1[k]) break
}
if (k<n) {
del[k] = 1
}
}
END {
for (k=0;k<n;k++)if (!del[k]) print pw0[k]
}

CaKiwi

After all is said and done, a lot more will have been said than done.
 
Hi marsd,

I tried your suggestion. It works, but it is the opposite of what I require. I need to compare two files and produce a new file with only the uniq lines. A second problem I ran into was that the FS needs to be : and I only want to compare the files by the first field only. ie. usr name.
If there is a match for user name then print the entire line only once into a third file which will become
/etc/passwd and then I will run pwconv.
 
Let me work on this and get back to you, in the meantime maybe somebody has an idea?
 
This works, but it is ugly.

#!/bin/sh
#globals
hold=&quot;/tmp/hold&quot;

echo -n &quot;Newnames file: &quot;
read f_file

for x in `cat $f_file`
do

awk -v a=$x ' {
FS = &quot;:&quot;
if ($1 !~ /a/) {
print $0
}
}' /etc/passwd | sort -u > $hold
#first create and erase previous entries.
#crap-I cannot process both at the same time.

awk -v c=$x ' {
FS = &quot;:&quot;
if ($1 ~ /c/) {
print $0
}
}' /etc/passwd | sort -u >> $hold

#then we append those names that match too

done
#That is ugly, but it takes all entries that do not match
#names in both files and those that do and appends the
#contents to the $hold file, sorted with no dupes.

Hope this works for you.
MMD
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top