How do I extract data from nmblookup in bash shell script?
Okay...
I am working on a BASH shell script that does a scan of a subnet with nmap and returns the "live" IP's in the specified range. That part works great. It's then supposed to query each "live" IP for it's NetBIOS hostname using nmblookup (I've got a Linux server playing PDC for a bunch of Windows workstations - all at a remote site). The problem is, I'm having trouble getting the data out of the nmblookup output. Once I have the IP, I do something like this: nmblookup -A <ip_address> In my script, <ip_address> is naturally replaced with a variable. The problem is, I get output like this (from nmblookup): Code:
PCNAME <00> - M <ACTIVE> I would imagine awk would do the job, and maybe even sed... but I'm not super savvy with either. I've used perl in the past (esp for one liners), but my perl skills are awfully rusty. I've tried a number of things, and none of them worked. I tried using grep and cut, but that didn't go well either. I thought perhaps I could use those two to get my variable out, and then use sed to remove the whitespace... but again, no go. I'm obviously doing something wrong. So is there an easy and efficient way to get this data out? |
Quote:
The other problem is that the output is multi-line, which eliminates line-oriented solutions like sed. All I can say is, catalog all the possible responses from nmblookup and deal with all of them. For this you need more coding skills. IOW you have bitten off more than you can comfortably chew, but you could certainly learn how to solve this problem. |
Quote:
Of course, whether you use sed or awk or whatever, the real requirement for a job like this is that first you have to find some kind of unique regular pattern to match. If you can determine that the data field you need always appears 2 lines after a certain fixed string, for example, or always appears at the beginning of a line and has 8-10 characters (and no other line does), or something like that, then it should be possible to come up with some way, though not necessarily a simple one, to extract it. You may need to use more than one pattern match to catch all the different variations you could encounter in the input. Just make sure that whatever pattern(s) you use can uniquely identify the data field you want without any false negatives or false positives. Also, are there any options you can use in nmblookup to output the data in a more convenient format? Or are there any other tools you can use to provide the same information? |
Given it's a multi-line output, and the results will vary if eg not a nmb host or whatever, then yes, catalogue all the expected result set types and figure how to match them. Allow for 'unmatched' ie one you didn't know could happen.
I'd personally do it in Perl, probably using a piped open or IPC::Open2 or IPC::Open3 . If I had to do it in shell, the easiest way would be to redirect the output into a temp file eg nmblookup.dat & then parse the file. Trying to do it on the fly in bash is tricky. PS good Perl examples/howto http://perldoc.perl.org/ http://www.perlmonks.org/?node=Tutorials |
Quote:
|
How about this
Code:
<whatever nmbscan command, with output redirected to nmbscan.out> |
@catkin
If the output stays like the provided example your example would print out the second line with officegroup and group. It also has the <00> in it. I'd go with some awk and would distinguish the line depending on the numbers of fields. Line 1 with the PCNAME has 5 fields where OFFICEGROUP lines have 6 fields. As long this holds true you could do something like this Code:
awk { if (NF == 5 ) print $1 Nother thing if you can be sure that the PCNAME always is the first line go with Code:
head -n 1 |
Quote:
Code:
<whatever nmbscan command, with output redirected to nmbscan.out> |
Beside of a little typo I don't understand why the improved version would print the PCNAME. M is also in both lines and not realy array[0] but array[3] inside the PCNAME line. :confused:
Code:
case "${array[1]}" in The typo I mentioned is right before the M or is it after? from the escape char you used I'd say its before ;) Code:
if [[ "${array[0]}" = 'M" ]]; then Code:
if [[ "${array[0]}" = "M" ]]; then |
Quote:
EDIT: actually the errors were *cough* *cough* a deliberate challenge :) |
Quote:
Sed may not always be the ideal choice for multi-line matches, but it's not really as bad as you're making it sound. It's often better than awk in such cases, at the very least. |
Quote:
|
Okay, hmm... lots of things to consider.
I can probably grep the first line out of the file. I know that's assuming a little, but I can live with that. At one point, I was able to get the name out, but it had all this white space on the sides. How would I use sed to remove the white space from a single line? Or, considering the perl factor. If I honed that data down to one line with grep, is there a one-liner (i.e. perl -pe "<CODE>") that would yank that variable name from the line? And if I could get it out, how do I stick the output from that perl one-liner and stuff it back into a BASH perl script? Help thus far is appreciated... any thoughts on this post? |
If you only had one line of data, use awk,; when it picks a field eg $3, doesn't care how much whitespace exists in between each non-whitespace value eg
Code:
asd fgh |
Quote:
Quote:
Always remember why there are so many tools (binarys) included with a linux distribution. They all do one thing very good. But this also leaves the challenge to the user which tool to use. Obvious the tool that fullfils the task (cause each and every tool just does it best ;)) So to make my point across and illustrate what I want to say lets take a look at the first line of the man pages of all the tools mentioned through out this thread. Code:
grep, egrep, fgrep, rgrep - print lines matching a pattern Code:
sed - stream editor for filtering and transforming text Code:
mawk - pattern scanning and text processing language Code:
head - output the first part of files Code:
cut - remove sections from each line of files I know this is overkill. I Just wanted to see you all how many tools there are and the more you know the better the chances that you'll find the right one for the job. It's just like moving when you have a loot of friends. It just flies. To boil things down. Either take the first line with head -n 1 or do the pattern matching of 5 fields within the PCNAME line. awk or the bash script will both suite you well |
All times are GMT -5. The time now is 03:05 AM. |