다음 hostlist.txt
과 같은 텍스트가 포함 된 파일 이 있습니다.
host1.mydomain.com
host2.mydomain.com
anotherhost
www.mydomain.com
login.mydomain.com
somehost
host3.mydomain.com
다음과 같은 작은 스크립트가 있습니다.
#!/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
명령의 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
경우 true가되고 중괄호 안의 명령이 실행됩니다. 첫 번째는 첫 번째 필드에서 후행을 제거합니다. 두 번째는 첫 번째 필드, 그,
뒤에, 마지막 필드를 인쇄합니다 . 세 번째 명령문f
은 0으로 재설정 됩니다 (false).다시 말해,
f
여기서 논리적 조건으로 작동합니다. 중괄호 안의 명령f
은 0이 아닌 경우 실행됩니다 (awk에서는 ‘true’를 의미 함). -
/ANSWER SECTION/{f=1}
현재 행에 string이 포함 된
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}'
awk
의 sub()
함수는 .
첫 번째 필드 끝에서 리터럴 기간을 제거하는 데 사용됩니다 . 그런 다음 awk
쉼표로 구분하여 필드 1과 5를 인쇄합니다.
참고 : hostlist.txt
해결되지 않은 항목 은 완전히 삭제되며 stdout 또는 stderr에는 표시되지 않습니다.
(Linux 및 FreeBSD에서 테스트)
답변
gawk
다음과 같이 호출을 변경하십시오 .
| gawk '{print substr($1,1,length($1)-1)","$NF}' >fqdn-ip.csv