다음과 같은 줄이 포함된 파일이 있습니다.
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