설명하다

설명하다

텍스트 파일이 있습니다. 다음과 같이 보입니다:

www.ac.com has address 6.1.1.146 www.ac.com is an alias for ac.com. www.ac.com is an alias for ac.com.
www.ba.net is an alias for www-bn.gs.ba.com. www-bn.gs.ba.com has address 11.28.11.4 ;; connection timed out; no servers could be reached

has address이전 및 이후 열을 추출 하여 쉼표로 구분하고 싶습니다 . 그래서 나는 다음을 얻고 싶습니다 :

www.ac.com,6.1.1.146
www-bn.gs.ba.com,11.28.11.4

어떻게 해야 하나요? 나는 이것을 시도했지만 awk '{print $1,$4}' myfile > newfile내가 원하는 것이 항상 열 1과 4에 있는 것은 아니기 때문에 잘 작동하지 않습니다. 관심 있는 열은 다양할 수 있지만 항상 구분됩니다 has address.

답변1

사용 grepsed:

grep -o '[^ ]* has address [^ ]*' | sed 's/ has address /,/'

나는 이것이 간단하기 때문에 좋아한다.


설명하다:

grep-o다음 패턴이 발견된 각 줄의 일치하는( ) 부분만 출력합니다.

  • 공백이 아닌( [^ ]*) 문자 has address뒤에 공백이 아닌( [^ ]*) 문자가 옵니다.

sedhas address간단히 다음 으로 대체됩니다 .,

답변2

존재하다 sed:

sed -r 's/(.* |^)([^ ]*) has address ([^ ]*)( .*|$)/\2,\3/' myfile > newfile

설명하다

  • sed -r 's/foo/bar/' myfile > newfile: sed"확장 정규식"( )과 함께 사용되므로 아래 캡처 그룹을 -r이스케이프할 필요가 없습니다 . ()발생 항목 foobar. 읽고 myfile쓰기 newfile.
  • (.* |^)([^ ]*) has address ([^ ]*)( .*|$)has address: 앞뒤에 공백이 1개 있는 문자열을 검색합니다 . 이 앞뒤에는 공백이 없는 문자열이 있어야 하며, 이를 그룹으로 캡처해야 합니다 ([^ ]*). 선행 단어 앞에는 공백(앞에 .*)이나 줄의 시작 부분(예: )이 와야 합니다 (.* |^). 다음 단어 뒤에는 공백(무엇이든 .*) 또는 줄 끝(예: )이 와야 합니다 ( .*|$).
  • \2,\3: 위 표현식은 전체 행을 캡처하므로 두 번째 및 세 번째 캡처 그룹인 before 및 after 단어로 대체됩니다 has address.

답변3

perl -nE '/(\S+) has address (\S+)/ and say "$1,$2"' x

답변4

존재하다 awk:

awk -v OFS=, '
  {
    for(i=1;i<NF;i++){
      j=i+1;
      if ($i=="has" && $j=="address") {
        domain=i-1;
        ip=i+2;
        print $domain,$ip;
        break;
      }
    }
  }'

필드를 반복합니다. "has"가 발견되고 다음 필드가 "address"인 경우 해당 필드 전후의 필드를 ,출력 필드 구분 기호로 인쇄합니다.

관련 정보