텍스트 파일이 있습니다. 다음과 같이 보입니다:
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
사용 grep
및 sed
:
grep -o '[^ ]* has address [^ ]*' | sed 's/ has address /,/'
나는 이것이 간단하기 때문에 좋아한다.
설명하다:
grep
-o
다음 패턴이 발견된 각 줄의 일치하는( ) 부분만 출력합니다.
- 공백이 아닌(
[^ ]*
) 문자has address
뒤에 공백이 아닌([^ ]*
) 문자가 옵니다.
sed
has address
간단히 다음 으로 대체됩니다 .,
답변2
존재하다 sed
:
sed -r 's/(.* |^)([^ ]*) has address ([^ ]*)( .*|$)/\2,\3/' myfile > newfile
설명하다
sed -r 's/foo/bar/' myfile > newfile
:sed
"확장 정규식"( )과 함께 사용되므로 아래 캡처 그룹을-r
이스케이프할 필요가 없습니다 .()
발생 항목foo
을bar
. 읽고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"인 경우 해당 필드 전후의 필드를 ,
출력 필드 구분 기호로 인쇄합니다.