ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
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.
All,
I have two files with user DN's that exported from two different LDAP directories. I wanted to write a script that reads(checks) users (cn=user1) in file A and check to see if users(cn=user1) exists in file B and give me nice output with what users are missing in file B.
I have around 30k users in file A with following format..
See this thread to determine how to write a loop in your script and then channel the line you read from file A into a grep command in file B, use the -c to get a count.
To do something this complex, I'd save the user name from file A and the "found count" from file B into an array defined in your script, and then process that array and create an output file using the entries where the found count is zero on a per-user basis.
A suggestion is to add:
set -x
set -v
Near the top of your script to output to stdout the flow of the script in order to debug it, and then later comment out those lines as you put the script into use.
Further, use functions instead of writing one big, hard to read script. If you aren't familiar with functions in a script, search for some examples, there are plenty.
awk -v "file1=path-to-file1" -v "file2=path-to-file2" '
BEGIN {
RS="[\t\n\v\f\r ]*[\r\n]+[\t\n\v\f\r ]*"
FS="[\t\v\f ]*[,][\t\v\f ]*"
# Read first file into list1
split("", list1)
while ((getline < file1) > 0)
for (i = 1; i <= NF; i++)
if ($i ~ /^[\t\v\f ]*[Cc][Nn][\t\v\f ]*=/) {
cn = tolower($i)
sub(/^[\t\v\f ]*[Cc][Nn][\t\v\f ]*=[\t\v\f ]*/, "", cn)
sub(/[\t\v\f ]*$/, "", cn)
list1[cn] = $0
}
# Read second file into list2
split("", list2)
while ((getline < file2) > 0)
for (i = 1; i <= NF; i++)
if ($i ~ /^[\t\v\f ]*[Cc][Nn][\t\v\f ]*=/) {
cn = tolower($i)
sub(/^[\t\v\f ]*[Cc][Nn][\t\v\f ]*=[\t\v\f ]*/, "", cn)
sub(/[\t\v\f ]*$/, "", cn)
list2[cn] = $0
}
# List all users in list1 that do not exist in list2.
for (cn in list1)
if (!(cn in list2))
printf("%s (%s)\n", cn, list1[cn])
}'
In the above code, I tell awk that records are separated by newlines, and any leading or trailing whitespace is part of the separator. Fields are separated by commas, again whitespace being a part of the comma.
I used two identical loops to read in the files. They check if one of the fields is the common name field (cn=), and if so, adds the entire record (as a string) into an associative array keyed by the value of the common name in lower case -- I assume you wish the comparison to be case insensitive. (If not, use $i instead of tolower($i).
The sub commands remove the cn= part and any leading and trailing whitespace.
Finally, the script loops over all names in cn1, and outputs the ones that are not listed in cn2.
Note that unlike normal awk scripts, this one has no input files. It would have been pretty natural to read only the second user list in the BEGIN section, and use a normal rule to process each record in the first file; however, I think you'll probably want to do the check the other way too -- list all users that are listed in the second file but not the first -- and you can only do both if you read both into arrays. So I'm anticipating your needs a bit.
Thanks for your help.
This is NOT home work. I been learning scripting. I'm taking the chances whereever I can write a script in my company. I wrote few sofar. Now I have a requirement that needs to compare couple of files time to time and need to make the changes to the directory based on what we find from comparison.
since I'm also learning, I dont wanna use someone else script. I want to write myself so that I can learn and help others in the future.
so back to my previous post on 04-01-11, 04:22 PM, I'm not sure why the single line splits into 2-3 or may be more line based on the spaces in between.
Quote:
cn=usera
one,ou=some,ou=some,o=org
cn=userb
one,ou=some,ou=some,o=org
cn=userb
one
test,ou=some,ou=some,o=org
but actual data is ..
Quote:
cn=usera one,ou=some,ou=some,o=org
cn=userb one,ou=some,ou=some,o=org
cn=userb one test,ou=some,ou=some,o=org
if I can get in a single line, I can put that in a variable and then using regular expression,I can get the (cn=*) and using that cn value I think I can compare with second file.
Grail - I'm not sure if your solution works bcz dn context is entirely different in two files most of the cases. but will test it when I have similar dn in both files.
I'm not sure why the single line splits into 2-3 or may be more line based on the spaces in between.
This one is easy, it is because your for loop performs word splitting based on the value of IFS, which by default is white space, hence each space passes an individual piece
into your line variable.
I am a little more with the fact that i misread the question that the cn=userX will be what you need to look for but the rest is irrelevant.
So how about:
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.