Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then 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.

Introduction to Linux - A Hands on Guide

This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.

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):

What I need to do is extract 'PCNAME' and stuff it in a variable. Naturally 'PCNAME' is going to be different each time.

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.

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):

What I need to do is extract 'PCNAME' and stuff it in a variable. Naturally 'PCNAME' is going to be different each time.

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?

No, not really. The problem is that you cannot say in advance what the data will look like. Sometimes nmblookup won't be able to provide the list you expect, sometimes the list will look different than you expect.

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.

The other problem is that the output is multi-line, which eliminates line-oriented solutions like sed.

That's not entirely true. Sed can operate over multiple lines. It's just a bit more tricky to do so. How difficult it is depends on just what you're trying to extract.

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.

Yes, and one can do Calculus with an abacus -- it's just very, very difficult. The OP is much better off using a solution in which multi-line matches are more intuitive, readable and understandable than is sed when processing multi-line tasks.

@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

and you should get the PCNAME. Maybe do a grep "<00>" beforehand so you only have to awk two lines.

Nother thing if you can be sure that the PCNAME always is the first line go with

Yes, and one can do Calculus with an abacus -- it's just very, very difficult. The OP is much better off using a solution in which multi-line matches are more intuitive, readable and understandable than is sed when processing multi-line tasks.

And as I said, it depends on exactly what you're trying to match. Matching one line and then grabbing something from the line immediately following it isn't all that hard to do. But if the data string you want can itself span multiple lines, for example, then yes, there are often better tools you can use.

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.

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?

I can probably grep the first line out of the file. I know that's assuming a little, but I can live with that.

If you only want the first line go with head -n 1. I bet to grep some unkown thing is too much even for grep xD.

Quote:

Originally Posted by utahnix

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.
Help thus far is appreciated... any thoughts on this post?

This also goes into the direction of David the H.
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

So if we don't have a pattern we can't realy use grep

Code:

sed - stream editor for filtering and transforming text

okay somehow we want to filter but we absolutly don't want to transform text. Makes it on the list

Code:

mawk - pattern scanning and text processing language

okay same aplies here like it does to grep put also one point for awk cause it process text. Makes it on the list

Code:

head - output the first part of files

If we dare we consider the first line to be hostname. So this is a total match.

Code:

cut - remove sections from each line of files

this would be good when we found our line. (Just summing up not taking experience into it)

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