다음 줄을 포함하는 파일이 있습니다
proto=tcp/http sent=144 rcvd=52 spkt=3
proto=tcp/https sent=145 rcvd=52 spkt=3
proto=udp/dns sent=144 rcvd=52 spkt=3
proto의 값, 즉 tcp/http
, tcp/https
, 을 추출해야 합니다 udp/dns
.
지금까지 시도해 보았지만 grep -o 'proto=[^/]*/'
값을 proto=tcp/
.
답변1
를 사용하려면 grep -o
추출하려는 내용과 정확히 일치해야 합니다. 문자열을 추출하고 싶지 않으므로 proto=
일치시키지 않아야 합니다.
tcp
udp
슬래시 및 비어 있지 않은 영숫자 문자열과 일치하거나 그 뒤에 오는 확장 정규식은 다음과 같습니다.
(tcp|udp)/[[:alnum:]]+
이것을 데이터에 적용하십시오:
$ grep -E -o '(tcp|udp)/[[:alnum:]]+' file
tcp/http
tcp/https
udp/dns
문자열로 시작하는 줄에서만 이 작업을 수행하려면 다음을 수행하십시오 proto=
.
grep '^proto=' file | grep -E -o '(tcp|udp)/[[:alnum:]]+'
첫 번째 공백 문자 sed
앞뒤의 모든 것을 사용하고 제거하십시오.=
$ sed 's/^[^=]*=//; s/[[:blank:]].*//' file
tcp/http
tcp/https
udp/dns
문자열로 시작하는 줄에서만 이 작업을 수행하려면 proto=
위와 동일한 전처리 단계를 삽입하거나 다음을 사용할 수 있습니다.grep
sed -n '/^proto=/{ s/^[^=]*=//; s/[[:blank:]].*//; p; }' file
-n
여기서는 기본 출력을 억제 한 다음 대체를 실행하고 해당 행이 일치하는 경우에만 해당 행을 명시적으로 인쇄하는 옵션을 사용합니다 ^proto=
.
의 경우 awk
기본 필드 구분 기호를 사용한 다음 첫 번째 필드를 분할 =
하고 두 번째 비트를 인쇄합니다.
$ awk '{ split($1, a, "="); print a[2] }' file
tcp/http
tcp/https
udp/dns
문자열로 시작하는 줄에서만 이 작업을 수행하려면 proto=
위와 동일한 전처리 단계를 삽입하거나 다음을 사용할 수 있습니다.grep
awk '/^proto=/ { split($1, a, "="); print a[2] }' file
답변2
GNU grep(옵션용)을 사용하는 경우 다음을 -P
사용할 수 있습니다.
$ grep -oP 'proto=\K[^ ]*' file
tcp/http
tcp/https
udp/dns
여기서는 proto=
문자열을 일치시켜 올바른 열을 추출했는지 확인한 다음 플래그를 사용하여 출력에서 이를 삭제합니다 \K
.
위의 내용에서는 열이 공백으로 구분되어 있다고 가정합니다. 탭도 유효한 구분 기호인 경우 공백이 아닌 문자와 일치하는 데 이를 사용하므로 \S
명령은 다음과 같습니다.
grep -oP 'proto=\K\S*' file
proto=
a와 같은 하위 문자열이 있는 필드 일치를 방지하려면 다음과 같이 thisisnotaproto=tcp/https
단어 경계를 추가할 수 있습니다 .\b
grep -oP '\bproto=\K\S*' file
답변3
사용 awk
:
awk '$1 ~ "proto" { sub(/proto=/, ""); print $1 }' input
$1 ~ "proto"
proto
첫 번째 열의 행에만 작업을 수행하도록 보장합니다.
sub(/proto=/, "")
proto=
입력에서 제거됩니다
print $1
나머지 열 인쇄
$ awk '$1 ~ "proto" { sub(/proto=/, ""); print $1 }' input
tcp/http
tcp/https
udp/dns
답변4
또 다른 grep
해결책:
grep -o '[^=/]\+/[^ ]\+' file
sed
일치하는 캡처 그룹만 인쇄하는 것과 유사합니다 .
sed -n 's/.*=\([^/]\+\/[^ ]\+\).*/\1/p' file