Bash – Разбить предыдущие параметры команд

Как разобрать предыдущую команду в bash?

Пример:

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

Цель:
Отправьте только ipaddress 1.2.3.4 на foo.txt


Я попытался использовать awk, но не нашел успеха

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

Я также попытался разобрать только цифры, используя sed

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

Соображения
1.2.3.4 всегда будет числом между 0.0.0.0 и 255.255.255.255
Имя пользователя foo может быть любой длины
foo@1.2.3.4 не обязательно является единственным параметром, переданным в ssh (например, ssh 1.2.3.4 -l foo)

Ресурсы
https://stackoverflow.com/questions/1733692/how-to-use-sed-awk-or-gawk-to-print-only-what-is-matched
https://stackoverflow.com/questions/2777579/sed-group-capturing
http://www.grymoire.com/Unix/Sed.html

Обновить
Дальнейшее уточнение
Конечной целью будет создание функции в моем .bashrc, которая позволит мне легко удалить конфликтный ключ ssh.

 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 

6 Solutions collect form web for “Bash – Разбить предыдущие параметры команд”

С вашим оригинальным синтаксисом:
$ cat /tmp/foo.txt | awk -F@ '{print $2}'
1.2.3.4

Если вы можете использовать другой синтаксис для команды ssh, это становится проще:

 ssh -l foo 1.2.3.4 echo !:3 

но для этого требуется такой точный синтаксис.

Вы можете использовать !! для доступа к предыдущей командной строке

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

может работать для вас, например

 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 

Единственное предположение здесь состоит в том, что ipaddress будет предшествовать @ и что после него есть пробел или конец строки.

Когда у вас был вывод на печать в файл, я буду использовать Perl:

 cat /tmp/foo.txt | \ perl -ne ' print $& if $_ =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/' 

Чтобы найти числовой IP-адрес из предыдущей команды ssh:

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

Я не вижу ничего в руководстве, которое позволит вам найти «аргумент, соответствующий шаблону» ( http://www.gnu.org/software/bash/manual/bashref.html#History-Interaction )

Довольно уверен, что вы не можете положить ! -style расширений истории внутри функции, но есть команда fc :

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

Это не будет препятствовать вам иметь IP-адрес как конкретный (например, последний) аргумент

 ssh user@1.2.3.4 hostname 

Нет конструкции расширения истории, чтобы сломать @ . Однако последний аргумент предыдущей команды также доступен как переменная $_ .

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

Обратите внимание, что это работает только в том случае, если имя узла было последним аргументом предыдущей команды: оно не будет работать, если предыдущей командой было, например, ssh somehost ls . Вы можете попытаться fc -ln -1 вывод fc -ln -1 чтобы извлечь первый аргумент без опции.


Ваша цель ставит меня как довольно плохую идею. Редко нужно удалить ключ хоста SSH – в основном это должно произойти только в том случае, если машина была переустановлена. Если вам нужно часто это делать, что-то не так с вашей методологией или, возможно, с настройкой сети (убедитесь, что ваши клиенты DHCP получают воспроизводимые IP-адреса, если вы никогда не подключаетесь к ним с другой машины).

  • Как подсчитать вхождения каждого слова, принадлежащего файлу, во все количество файлов `n`, переданных в качестве аргументов?
  • Чтобы удалить лишнее пространство из строки с помощью команды оболочки
  • sed соответствует только во второй строке
  • Как читать несколько строк вместо строк
  • sed: захват и замена всех данных между последней обратной косой чертой и запятой
  • Почему не матч SHA?
  • Удалить строку, если два шаблона найдены в одной строке
  • array выводит все испорченные?
  • Как sed заменить этот конец линии?
  • Преобразование простых данных в json-файл
  • замените с начала строки на 1 из нескольких шаблонов в конец другой строки со вторым шаблоном
  • Linux и Unix - лучшая ОС в мире.