sed 또는 awk를 다시 호출하지 않고 문자열에서 점 문자를 어떻게 제거합니까? \

다음 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경우 변수 f1(true)로 설정됩니다 .

    여기서 /ANSWER SECTION/논리적 조건으로 사용됩니다. 전류가 정규식과 일치하면 true로 평가됩니다 ANSWER SECTION. 그렇다면 중괄호 안의 명령이 실행됩니다.


답변

dig호스트 이름 목록이 포함 된 파일을 읽고 하나씩 처리 할 수 ​​있습니다. dig답변 섹션을 제외한 모든 출력을 억제하도록 지시 할 수도 있습니다 .

원하는 결과를 얻을 수 있습니다.

dig -f hostlist.txt +noall +answer +search |
    awk '{sub(/\.$/,"",$1); print $1","$5}'

awksub()함수는 .첫 번째 필드 끝에서 리터럴 기간을 제거하는 데 사용됩니다 . 그런 다음 awk쉼표로 구분하여 필드 1과 5를 인쇄합니다.

참고 : hostlist.txt해결되지 않은 항목 은 완전히 삭제되며 stdout 또는 stderr에는 표시되지 않습니다.

(Linux 및 FreeBSD에서 테스트)


답변

gawk다음과 같이 호출을 변경하십시오 .

| gawk '{print substr($1,1,length($1)-1)","$NF}' >fqdn-ip.csv