Tengo un archivo llamado hostlist.txt
que contiene texto como este:
host1.mydomain.com
host2.mydomain.com
anotherhost
www.mydomain.com
login.mydomain.com
somehost
host3.mydomain.com
Tengo el siguiente script pequeño:
#!/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
Qué salidas a 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
Mi pregunta es ¿cómo elimino el .
justo antes de la coma sin invocar sed
o de gawk
nuevo? ¿Hay algún paso que pueda realizar en las llamadas existentes sed
o gawk
que eliminen el punto?
hostlist.txt
contendrá miles de hosts, por lo que quiero que mi script sea rápido y eficiente.
shell-script
awk
sed
regular-expression
string
Linoob
fuente
fuente
dig +short
que no funciona para ti?Respuestas:
El
sed
comando, elawk
comando y la eliminación del período final se pueden combinar en un solo comando awk:O, como se extiende sobre varias líneas:
Debido a que el
awk
comando sigue ladone
declaración, soloawk
se invoca un proceso. Aunque la eficiencia puede no importar aquí, esto es más eficiente que crear un nuevo proceso sed o awk con cada ciclo.Ejemplo
Con este archivo de prueba:
El comando produce:
Cómo funciona
awk lee implícitamente su entrada un registro (línea) a la vez. Este script awk usa una sola variable,
f
que indica si la línea anterior era un encabezado de sección de respuesta o no.f{sub(/.$/,"",$1); print $1", "$NF; f=0}
Si la línea anterior era un encabezado de sección de respuesta,
f
será verdadera y se ejecutarán los comandos entre llaves. El primero elimina el período final del primer campo. El segundo imprime el primer campo, seguido de,
, seguido del último campo. La tercera declaración se restablecef
a cero (falso).En otras palabras,
f
aquí funciona como una condición lógica. Los comandos entre llaves se ejecutan sif
no es cero (que, en awk, significa 'verdadero')./ANSWER SECTION/{f=1}
Si la línea actual contiene la cadena
ANSWER SECTION
, entonces la variablef
se establece en1
(verdadero).Aquí,
/ANSWER SECTION/
sirve como una condición lógica. Se evalúa como verdadero si la corriente coincide con la expresión regularANSWER SECTION
. Si lo hace, entonces el comando entre llaves se ejecuta.fuente
f
una variable arbitraria o esf{}
una parte explícita de la funcionalidad de awk?f
Es una variable arbitraria. En realidad, puede anteponer las{}
complejas condiciones lógicas.f
es una condición lógica muy simple: es verdadero si no es cero, falso si es cero./ANSWER SECTION/
desempeña el papel de condición lógica, análoga al papelf
desempeñado en el primer comando. He actualizado la respuesta para discutir esto.dig
puede leer en un archivo que contiene una lista de nombres de host y procesarlos uno por uno. También puede indicardig
que suprima todos los resultados, excepto la sección de respuesta.Esto debería darle la salida que desea:
awk
Lasub()
función de se utiliza para eliminar el período literal.
desde el final del primer campo. Luegoawk
imprime los campos 1 y 5 separados por una coma.NOTA: las entradas
hostlist.txt
que no se resuelven se descartan por completo; no aparecen en stdout O stderr.(Probado en Linux y FreeBSD)
fuente
Cambie su invocación de
gawk
a lo siguiente:fuente