sed 또는 awk를 다시 호출하지 않고 어떻게 문자열에서 점 문자를 제거할 수 있나요?

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.txt1000개의 호스트가 포함되므로 스크립트가 빠르고 효율적이기를 바랍니다.

답변1

Commands 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가 되며 중괄호 안의 명령이 실행됩니다. 첫 번째는 첫 번째 필드에서 후행 마침표를 제거합니다. 두 번째는 첫 번째 필드를 인쇄한 다음 ,마지막 필드를 인쇄합니다. 세 번째 문은 f0(false)으로 재설정됩니다.

    즉, f여기서는 논리적 조건이 중요한 역할을 합니다. f0이 아닌 경우(awk에서 "true"를 의미) 중괄호로 묶인 명령이 실행됩니다.

  • /ANSWER SECTION/{f=1}

    현재 줄에 문자열이 포함되어 있으면 ANSWER SECTION이 변수는 (true) f로 설정됩니다 .1

    여기서는 /ANSWER SECTION/논리적 조건으로 작용합니다. 현재 값이 정규식과 일치하면 해당 값은 true입니다 ANSWER SECTION. 그렇다면 중괄호로 묶인 명령을 실행하십시오.

답변2

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에서 테스트됨)

답변3

호출을 gawk다음으로 변경하십시오.

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

관련 정보