Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have this output from a find command:

abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23

where abc,def and geh are device names and could be of any length and others are IP address belong to devices. Likeabc,10.11.13.14 for device abc. IP shall be next to comma delimiter.

How can I use sed, grep or awk to print the associated IP when I grep for a device name? In short I want the IP to be displayed next to device name.

share|improve this question

5 Answers 5

I am more comfortable with awk, so I would like to present two solutions in awk.

Solution 1

$ echo abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23 | awk -F, '{for (i=1; i<NF; i+=2) if ($i == "def") print $(i+1)}'
1.2.3.4

In this case, I am looking for a machine name "def", if found, print the next column.

Solution 2

$ echo abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23 | tr , \\n | awk '/def/ {getline;print}'
1.2.3.4

In this solution, I use the tr command to convert commas to new line, search for "def" and print the line that follows. I hope these solutions work for you.

share|improve this answer
    
Thanks you so much Mr Hai Vu for your kind assitance both the solution worked in my case.... –  user28011 Nov 29 '12 at 9:29

Assuming you have GNU grep with Perl-compatible regular expressions:

device="def"
grep -oP '(?<=\b'"$device"',).*?(?=,|$)'

Which means: find the content between "def," on one side and "a comma or end-of-line" on the other

EDIT: added a word boundary to the RE to find the given device more precisely.

share|improve this answer
    
What if there's both a def and xdef device? –  Stéphane Chazelas Nov 29 '12 at 21:35
    
@StephaneChazelas (?:(?<=,def,)|(?<=^def,)) –  Gilles Nov 29 '12 at 22:43

Without using any command but shell builtins:

string='abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23'
dev=def

s=,$string,
case $s in
  (*,"$dev",*) ip=${s#*",$dev,"}; ip=${ip%%,*};;
  (*) ip=unknown
esac

printf '%s\n' "$ip"

With zsh, it's easy to map that string to an associative array:

string='abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23'
typeset -A ip
ip=(${(s:,:)string})
print -r -- $ip[def]
share|improve this answer

Using grep(GNU) and cut:

$ echo abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23 | grep -o 'abc,[^,]*'  | cut -d, -f2
10.11.13.14
share|improve this answer
    
Thanks for the response Guru but its showing for a .... What is the significance of a ? –  user28011 Nov 29 '12 at 9:31
    
ohh..i have this habit of using filenames like a, b , etc..its just the file name..removing it.... –  Guru Nov 29 '12 at 9:34
    
You command has a double quote " that should not be there. –  Hai Vu Nov 29 '12 at 14:19
    
the problems of editing at the last minute :) thanks Hai Vu. –  Guru Nov 29 '12 at 14:21

Substitute every IP-address [0-9\.]\{7,15\} using sed. An IP address consists of numbers and dots, varying from 7 to 15 positions.

Replace every IP-address with itself followed by a newline \n, which basically means that every device,IP-combination will have its own line.

echo "abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23" | sed 's/\([0-9\.]\{7,15\}\),/\1\n/g' 
abc,10.11.13.14
def,1.2.3.4
geh,6.7.54.23


echo "abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23" | sed 's/\([0-9\.]\{7,15\}\),/\1\n/g'  | grep def
def,1.2.3.4
share|improve this answer
    
Thanks for the response Jippie –  user28011 Nov 29 '12 at 9:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.