Tengo un archivo llamado hostlist.txtque 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 sedo de gawknuevo? ¿Hay algún paso que pueda realizar en las llamadas existentes sedo gawkque 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 +shortque no funciona para ti?Respuestas:
El
sedcomando, elawkcomando 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
awkcomando sigue ladonedeclaración, soloawkse 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,
fque 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,
fserá 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 restablecefa cero (falso).En otras palabras,
faquí funciona como una condición lógica. Los comandos entre llaves se ejecutan sifno es cero (que, en awk, significa 'verdadero')./ANSWER SECTION/{f=1}Si la línea actual contiene la cadena
ANSWER SECTION, entonces la variablefse 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
funa variable arbitraria o esf{}una parte explícita de la funcionalidad de awk?fEs una variable arbitraria. En realidad, puede anteponer las{}complejas condiciones lógicas.fes 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 papelfdesempeñado en el primer comando. He actualizado la respuesta para discutir esto.digpuede leer en un archivo que contiene una lista de nombres de host y procesarlos uno por uno. También puede indicardigque suprima todos los resultados, excepto la sección de respuesta.Esto debería darle la salida que desea:
awkLasub()función de se utiliza para eliminar el período literal.desde el final del primer campo. Luegoawkimprime los campos 1 y 5 separados por una coma.NOTA: las entradas
hostlist.txtque no se resuelven se descartan por completo; no aparecen en stdout O stderr.(Probado en Linux y FreeBSD)
fuente
Cambie su invocación de
gawka lo siguiente:fuente