У меня есть этот «раздел ответов» из звонка dig:
www.google.com 300 IN A \<ip_address\>
Я хочу извлечь поддомен www из www.google.com, чтобы сохранить его в переменной.
Я попытался использовать sed, чтобы отфильтровать имя поддомена, а затем заменить первое поле (т. е. $1) после перехода к awk на $host_name, например:
host_name=$(echo get_dig "$@" | sed 's/..*//; s/ .*//')
...
get_dig "$@" | awk '{ $1 = $host_name; printf("The subdomain %s is a %s record and points to %s\\n", $1, $4, $5) }'
NB: get_dig — это функция оболочки, которую я создал для запуска dig и извлечения «раздела ответов».
Я протестировал, и часть sed обрезается, как я ожидаю, и дает правильный результат (т. имя хоста в строке www. Кроме того, я объявил $1 глобально.
PS: я должен использовать awk, но возможно, что я мог заглянуть в конкретный процесс с помощью $host_name





Вам никогда не понадобится sed, если вы используете awk. Я думаю, это то, что вы пытаетесь сделать, используя любой awk:
echo 'www.google.com 300 IN A \<ip_address\>' |
awk '{
sub(/\..*/,"",$1);
printf "The subdomain %s is a %s record and points to %s\n", $1, $4, $5
}'
The subdomain www is a A record and points to \<ip_address\>
Замените echo '...' на get_dig "$@" (которого у меня явно нет).
Что касается того, почему ваш скрипт не работал, см. Как использовать переменные оболочки в скрипте awk? и избавьтесь от echo перед get_dig в трубе к sed.
Получите книгу «Эффективное программирование AWK, 5-е издание» Арнольда Роббинса, но sub() описан на каждой справочной странице awk, например. man7.org/linux/man-pages/man1/awk.1p.html , поэтому я не уверен, в какой документации вы просматривали ее, но избавьтесь от этой документации. Это также описано в спецификации POSIX awk, pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html.
после покупки книги вы также можете использовать соответствующий справочный материал по адресу gnu.org/software/gawk/manual/gawk.html#String-Functions.
awk '{ $1 = $host_name; printf("The subdomain %s is a %s record and points to %s\\n", $1, $4, $5) }'
Вы пытаетесь получить доступ к host_name-му полю строки, если вы хотите использовать переменную оболочки внутри команды awk, вы должны вставить ее, используя один из
-v var=val
--assign var=val
Рассмотрим следующий простой пример
host_name = "www"
echo "uno dos tres" | awk -v host_name = "$host_name" '{$1=host_name; printf("Subdomain %s is %s and points to %s\n",$1,$2,$3)}'
дает вывод
Subdomain www is dos and points to tres
Примечание. Я использую echo "uno dos tres" вместо вашей команды.
(проверено в GNU Awk 5.1.0)
@EdMorton Я улучшил свой ответ
если вы просто хотите извлечь поля из ответа dig, вот быстрый способ разделить его. Форматирование тривиально с этого момента:
dig +noall +answer www.google.com |
gtee >( gcat -n >&2; ) |
1 www.google.com. 112 IN A 142.250.80.36
mawk NF=NF FS='[.][^ \t]+[ \t]+|[ \t].+[ \t]' OFS='\f'
www
112
142.250.80.36
Ваш ответ отлично сработал и дал желаемый результат. Это избавило меня от необходимости использовать
sedи отслеживать другую переменную, так что спасибо за это! Из-за этого я много читалawk, но почему-то не наткнулся на этуsubфункцию. Есть лиawkдокументация, на которую вы могли бы мне направить, чтобы я мог больше узнать о сабвуфере и другихawkфункциях.