Как удалить символ точки из строки без вызова sed или awk снова?
У меня есть файл hostlist.txt
который содержит текст:
host1.mydomain.com host2.mydomain.com anotherhost www.mydomain.com login.mydomain.com somehost host3.mydomain.com
У меня есть следующий небольшой скрипт:
- Как хранить цветной текст в переменной и печатать его с цветом позже?
- grep отлично работает в командной строке, но ничего не возвращает в скрипте
- как изменить один столбец и добавить другие столбцы в строке awk
- Symlink для файла, который еще не существует
- Как вы определяете доступность файловой системы из сценария bash?
#!/usr/local/bin/bash while read host; do dig +search @ns1.mydomain.com $host ALL \ | sed -n '/;; ANSWER SECTION:/{n;p;}'; done <hostlist.txt \ | gawk '{print $1","$NF}' >fqdn-ip.csv
Какие выходные данные для fqdn-ip.csv
:
host1.mydomain.com.,10.0.0.1 host2.mydomain.com.,10.0.0.2 anotherhost.internal.mydomain.com.,10.0.0.11 www.mydomain.com.,10.0.0.10 login.mydomain.com.,10.0.0.12 somehost.internal.mydomain.com.,10.0.0.13 host3.mydomain.com.,10.0.0.3
Мой вопрос: как удалить .
как раз перед запятой без повторного вызова sed
или gawk
? Есть ли способ, который я могу выполнить в существующих вызовах sed
или gawk
которые будут линять точку?
hostlist.txt
будет содержать 1000 хостов, поэтому я хочу, чтобы мой скрипт был быстрым и эффективным.
- Использовать команду sed с переменными
- Как я могу перечислить содержимое архивного архива без его запуска?
- Вывод в переменной не должен интерпретироваться как команда
- как создать скрипт для создания резервной копии gpg?
- запись общего времени выполнения в сценарии bash
- Как поместить команду EOF в одну строку для выполнения нескольких команд оболочки
- Функция Bash присваивает значение переданному параметру
- Убедитесь, что переменная имеет определенное количество пробелов
3 Solutions collect form web for “Как удалить символ точки из строки без вызова sed или awk снова?”
Команда sed
команда awk
и удаление конечного периода могут быть объединены в одну команду awk:
while read -r host; do dig +search "$host" ALL; done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
Или, как разброс по нескольким линиям:
while read -r host do dig +search "$host" ALL done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
Поскольку команда awk
следует за заявлением done
, вызывается только один awk
процесс. Хотя эффективность здесь не имеет значения, это более эффективно, чем создание нового sed или awk-процесса с каждым циклом.
пример
С этим тестовым файлом:
$ cat hostlist.txt www.google.com fd-fp3.wg1.b.yahoo.com
Команда производит:
$ while read -r host; do dig +search "$host" ALL; done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}' www.google.com, 216.58.193.196 fd-fp3.wg1.b.yahoo.com, 206.190.36.45
Как это работает
awk неявно считывает свой вход по одной записи (строке) за раз. Этот awk-скрипт использует одну переменную f
, которая сигнализирует, была ли предыдущая строка заголовком секции ответа или нет.
-
f{sub(/.$/,"",$1); print $1", "$NF; f=0}
Если предыдущая строка была заголовком раздела ответа, то
f
будет истинным, а команды в фигурных скобках будут выполнены. Первый удаляет конечный период из первого поля. Второй печатает первое поле, за которым следует, за которым следует последнее поле. Третий оператор сбрасываетf
до нуля (false).Другими словами,
f
здесь функционирует как логическое условие. Команды в фигурных скобках выполняются, еслиf
отличен от нуля (что в awk означает «true»). -
/ANSWER SECTION/{f=1}
Если текущая строка содержит строку
ANSWER SECTION
, то переменнаяf
устанавливается в1
(true).Здесь
/ANSWER SECTION/
служит логическим условием. Он оценивает значение true, если текущий соответствует регулярному выражениюANSWER SECTION
. Если это так, то команда в фигурных скобках выполняется.
dig
может читать в файле, содержащем список имен хостов, и обрабатывать их один за другим. Вы также можете сообщить dig
для подавления всех выходных данных, кроме раздела ответа.
Это должно дать вам требуемый результат:
dig -f hostlist.txt +noall +answer +search | awk '{sub(/\.$/,"",$1); print $1","$5}'
Функция sub()
awk
используется для полосового литерального периода .
от конца первого поля. Затем awk
печатает поля 1 и 5, разделенные запятой.
ПРИМЕЧАНИЕ. Записи в hostlist.txt
которые не разрешены, полностью отбрасываются – они не отображаются на stdout OR stderr.
(Проверено на Linux и FreeBSD)
Измените ваш вызов gawk
следующим образом:
| gawk '{print substr($1,1,length($1)-1)","$NF}' >fqdn-ip.csv