Linux - NewbieThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have a file with first name in first column and their status as "Active" or "Inactive" in second column. It is a very large file with 40 thousands users. I need to split the file into two. One named Active including only active users and the other named Inactive including inactive users.
It is kind of complicated. Let me try.
db user list:
--------------
a active
b active
c inactive
d active
e inactive
etc/passwd user list:
----------------
a
c
f
g
h
resultant combined file:
-------------------------
a
a active
b active
c inactive
c
d active
e inactive
f
g
h
What i want is:
-----------------
c inactive user exists in both db and etc/paaswd
e inactive user exists only in db
f rogue user
g rogue user
h rogue user
i got confused on how to tackle it. should i split or .....if i split then it becomes difficult to join without the words active and inactive to segregate the users. what i want to achieve is the last table above.
How to get this?
---------- Post added 11-08-12 at 02:01 PM ----------
so you see, I am not concerned about active users and dont want them to reflect in the final file
CREATE TABLE users_passwd(username);
CREATE TABLE users_active(username, active);
.separator ' '
.import users-passwd.txt users_passwd
.import users-db.txt users_active
SELECT users_passwd.username, 'inactive user exists in both db and etc/passwd'
FROM users_passwd, users_active WHERE users_active.active = 'inactive'
AND users_passwd.username = users_active.username;
SELECT username, 'inactive user exists only in db'
FROM users_active WHERE active = 'inactive'
AND username NOT IN users_passwd;
SELECT username, 'rogue user'
FROM users_passwd
WHERE username NOT IN (SELECT username FROM users_active);
Code:
% sqlite3 < check-users.sql
c inactive user exists in both db and etc/passwd
e inactive user exists only in db
f rogue user
g rogue user
h rogue user
I appreciate ntubski but i will go with druuna because I am to do it in bash. I am only allowed to get one file from the db and that is given.
---------- Post added 11-09-12 at 11:53 AM ----------
This is what I had and I was going in circles. I searched and tested a lot.
#! /bin/bash
CMD="use metadata; select usernames.SNo, usernames.DataTelid, usernames.UName, personaldata.ActiveInactive from usernames, personaldata where usernames.DataTelid=personaldata.DataTelid ORDER By usernames.UName, personaldata.ActiveInactive into outfile '/tmp/querydb';"
#echo Above are the inactive users that exist in etcpasswd list. Intruder alert.
diff /tmp/strpdb /tmp/userlist | grep '{print $1}' | sed "s/^> \(.*\)/\1 ---> Rogue User/;s/^<\(.*\)/\1 <-------Ignore this Inactive user. Only exists in database/"
Sorry I meant I appreciate both druuna (he shows how to compare with etc/passwd) and ntubski (he gives me the sql files). I need to put them together so they work in order
@ntubski, now that you see my code and the cloud i am in, i am not to sure if what you suggested fits what i want. I can only decide rogue user if the user only exists in etc/password and does not in my db file that i got from the sql query.
@druuna please explain below
#!/bin/bash -> got it
awk 'BEGIN { -> got it
FS = "[: ]" -> got it
while ( ( getline < "/etc/passwd" ) > 0 ) _[$1] = $1 -> are we stripping the file to column $1, meaning just for the usernames???
}
{ _[$1] = _[$1]" "$2 } -> I am not to sure whats happening here
END {
for ( i in _ ) { -> Why _ ?
if ( _[i] !~ / active/ ) { -> Please justify ?
if ( i ~ _[i] ) { print i > "users.rogue" }
if ( _[i] ~ /^ inactive/ ) { print i > "users.inactive.db.only" }
if ( _[i] ~ /. inactive/ ) { print i > "users.inactive.in.both" }
}
}
}' db.users.list
awk 'BEGIN {
# blue part is done before reading db.users.list
# set the 2 needed separators (: or a space)
FS = "[: ]"
# read the user names from /etc/passwd and store them in an array. username is also the index.
while ( ( getline < "/etc/passwd" ) > 0 ) _[$1] = $1
}
# brown part is done for each line in db.users.list
# store or add field 2 from db.users.list.
# If the entry already exist a space and field 2 is added to the username,
# if it doesn't exist a space and field 2 is stored in a new array entry.
{ _[$1] = _[$1]" "$2 }
END {
# green part is done when db.users.list is completely read
# array now holds all usernames present in /etc/passwd and db.users.list. some of those have an extra field (active/inactive)
# for all entries in array
for ( i in _ ) {
# dismiss array entries that contain a space followed by active
if ( _[i] !~ / active/ ) {
# print user only entries
if ( i ~ _[i] ) { print i > "users.rogue" }
# print lines that start with a space followed by inactive
if ( _[i] ~ /^ inactive/ ) { print i > "users.inactive.db.only" }
# print lines that contain any character followed by a space followed by inactive
if ( _[i] ~ /. inactive/ ) { print i > "users.inactive.in.both" }
}
}
}' db.users.list
Last edited by druuna; 11-10-2012 at 07:47 AM.
Reason: made it a bit more readable
Sorry I meant I appreciate both druuna (he shows how to compare with etc/passwd) and ntubski (he gives me the sql files). I need to put them together so they work in order
My solution happened to use sql (specifically, sqlite), but it takes as input the text files that were extracted from the /etc/passwd (users-passwd.txt) and the database (users-db.txt). It does NOT interact at all with your actual database.
Both solutions do pretty much the same thing (the output format is a bit different); druuna's solution saves you the extra step of reading from /etc/passwd.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.