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.

How would one parse the previous command in bash?

Example:

root$ ssh foo@1.2.3.4
root$ echo !$ &>/tmp/foo.txt
root$ cat /tmp/foo.txt
foo@1.2.3.4

Goal:
Send just the ipaddress 1.2.3.4 to foo.txt


I've attempted to used awk, but have not found success

#doesn't work
cat /tmp/foo.txt |awk '{print $2,$3,$4}' 

I've also attempted to parse out just the digits using sed

#doesn't work
sed 's/.//p' /tmp/foo.txt 
sed 's/[0-9]//p' /tmp/foo.txt

Considerations
1.2.3.4 will always be a number between 0.0.0.0 and 255.255.255.255
The user name foo can be any length
foo@1.2.3.4 is not necessarily the only parameter passed into ssh (eg.. ssh 1.2.3.4 -l foo)

Resources
http://stackoverflow.com/questions/1733692/how-to-use-sed-awk-or-gawk-to-print-only-what-is-matched
http://stackoverflow.com/questions/2777579/sed-group-capturing
http://www.grymoire.com/Unix/Sed.html

Update
Further Clarification
The end goal will be to create a function in my .bashrc that will allow me to easily remove a conflicting ssh key.

root$ ssh foo@1.2.3.4  
#some big error message warning about man in the middle attack
root$ ssh-keygen -R 1.2.3.4
share|improve this question
add comment

migrated from serverfault.com Jul 22 '13 at 20:06

This question came from our site for professional system and network administrators.

6 Answers

up vote 5 down vote accepted

With your original syntax:
$ cat /tmp/foo.txt | awk -F@ '{print $2}'
1.2.3.4

share|improve this answer
    
+1 for the simplest solution so far –  spuder Jul 22 '13 at 18:37
1  
@John. cat is not needed. awk -F@ '{print $2}' /tmp/foo.txt does the same without invoking cat –  val0x00ff Jul 24 '13 at 10:33
    
Canonical partmaps.org/era/unix/award.html#uucaletter –  Penz Jan 23 at 20:42
add comment

If you can use another syntax for the ssh command, it get's easier:

ssh -l foo 1.2.3.4 
echo !:3 

but this requires this exact syntax.

share|improve this answer
    
+1, This is a good idea. Very elegant. I'd prefer to not retrain myself to use the -l every time tough. –  spuder Jul 22 '13 at 18:38
add comment

You can use !! to access the previous command line so

echo !! | sed 's/.*@\(.*\).*/\1/' | awk '{print $1}'

may work for you e.g.

echo ssh user@123.456.654.321 ls | ...
123.456.654.321

echo ssh -p 19111 user@123.456.654.321 | ...
123.456.654.321

The only assumption here is that the ipaddress will be preceded by an @ and that there is a space or end of line after it.

share|improve this answer
add comment

When you had print output to a file, I will use Perl:

cat /tmp/foo.txt | \
perl -ne ' print $& if $_ =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/'
share|improve this answer
add comment

To find a numeric IP address from the previous ssh command:

echo $(grep -oP '\d+\.\d+\.\d+\.\d+' <<< "!ssh")

I don't see anything in the manual that would let you find "an argument matching a pattern" (http://www.gnu.org/software/bash/manual/bashref.html#History-Interaction)

Pretty sure you can't put !-style history expansions inside a function, but there's the fc command:

# return the IP address of the most recent ssh command
sship () { command grep -oP '\d+\.\d+\.\d+\.\d+' < <(fc -l ssh); }

This will not constrain you to have the ip address as a specific (e.g. the last) argument

ssh user@1.2.3.4 hostname
share|improve this answer
add comment

There's no history expansion construct to break at @. However the last argument of the previous command is also available as the variable $_.

ssh-keygen -R "${_##*@}"

Note that this only works if the host name was the last argument of the previous command: it won't work if the previous command was e.g. ssh somehost ls. You can attempt parsing the output of fc -ln -1 to extract the first non-option argument.


Your goal strikes me as a rather bad idea. It is rare to need to remove an SSH host key — basically it should only happen if the machine has been reinstalled. If you need to do that often, something is wrong with your methodology, or perhaps with your network setup (make sure that your DHCP clients get reproducible IP addresses unless you're never ever going to connect to them from another machine).

share|improve this answer
    
Thanks for the input. Myself and others create and destroy dozens of openstack instances per week for testing. You can see additional details about why I get so many conflicting ssh keys on this question serverfault.com/questions/506864/… –  spuder Jul 23 '13 at 4:01
add comment

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.