awk 및 ss의 출력을 사용하여 네 번째 열을 인쇄하려고 합니다. 때로는 작동하지만 때로는 열을 잘못 병합하거나 분할하는 경우도 있습니다. 몇 가지 다른 FS 옵션을 시도했는데 여기에는 필드 헤더에 공백이 포함되어 있기 때문에 두 개 이상의 공백이 있습니다.
이렇게 하면 다섯 번째 열과 빈 헤더가 제공됩니다.
$ ss -tn
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 36 172.31.19.34:22 172.115.128.85:64478
ESTAB 0 0 [::ffff:172.31.19.34]:80 [::ffff:172.115.128.85]:65446
$ ss -tn | awk -F '[[:space:]][[:space:]]+' '{print $4}'
172.115.128.86:64478
[::ffff:172.115.128.86]:65446
여기서 동일한 명령을 사용하면 내가 원하는 네 번째 열이 제공됩니다.
$ ss -tn
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 36 172.31.19.34:22 172.115.128.85:64478
$ ss -tn | awk -F '[[:space:]][[:space:]]+' '{print $4}'
Local Address:Port
172.31.19.34:22
아마도 더 쉬울 것이라는 것을 알고 있지만 추가 처리를 원하기 때문에 cut
사용하고 있습니다 .awk
세부 정보 추가: ss가 왜 이 IPv6 스타일 주소를 표시하는지 잘 모르겠습니다. 이것은 내 노트북에서 Apache 서버로의 연결이지만 내 노트북에는 IPv6 주소가 없습니다.
답변1
~처럼무루힌트를 주다논평, awk
계속 작동할 수 있습니다. 달라질 수 있는 것은 출력의 간격입니다 ss
.
결과 ss -nt
1은 7개의 열을 출력하고 제목은 , State
, Recv-Q
, Send-Q
, Local Address
, Port
, Peer Address
입니다 Port
. 네 번째와 다섯 번째 열은 :
콜론( )으로 구분됩니다. 여섯 번째와 일곱 번째 열도 마찬가지입니다. 다른 모든 콘텐츠는 공백 문자로 구분됩니다.
모든 열은 정렬이 필요한 공간으로 채워집니다. 네 번째와 여섯 번째 패딩은 왼쪽에 있고 다른 모든 패딩은 오른쪽에 있습니다.
추가 패딩이 발생할 수 있습니다.
출력이
ss -nt
터미널로 전달되는 경우:해당 행의 최소 길이(각 필드의 가장 긴 내용과 최소 간격(6자)의 합으로 계산됨)이 터미널 너비보다 작은 경우 각 행은 균등하게 패딩하여 터미널 너비로 확장됩니다. 공백이 있는 모든 열.
그렇지 않으면 줄이 끊어지고 필드가 줄을 따라 정렬됩니다(위와 같이 터미널 너비까지 채워짐).
출력이
ss -nt
터미널로 전달되지 않는 경우(예: 일반 파일로 파이프되거나 리디렉션되는 경우) 행의 실제 길이는 최소 80의 배수로 정의되며, 이는 위에 정의된 최소 길이보다 높습니다. 모든 열은 총 행 길이(80, 160, 240, ... 문자 2 ) 를 달성하기 위해 공백으로 균등하게 채워집니다 .
따라서 두 열이 두 개 이상의 공백으로 분리된다는 보장이 없으므로 분할 시 시퀀스를 신뢰할 수 없게 됩니다.
ss -tn
그럼에도 불구하고 열 헤더는 알려져 있고 고정되어 있으며 해당 열에는 헤더 이외의 공백이 포함되어서는 안 된다는 점을 참고하여 상당히 안전한 방법으로 출력을 처리할 수 있습니다 .
ss -nt | sed '
1 s/[ ]Address:/_Address|/g # Remove the known spaces from column
# headers; also, change ":" into "|"
s/:\([^:|]*[ ]\)/|\1/g # Change the colons used as separators
# into vertical bars "|", to avoid
s/:\([^:|]*\)$/|\1/g # confusion with those in IPv6s
' | awk -v FS='\\||[ ]+' -v OFS=":" ' # Split on sequences of one or more
{ print $4,$5 } # spaces OR on any vertical bar
'
그러면 콜론으로 구분된 네 번째 및 다섯 번째 열(로컬 주소 및 포트)만 인쇄됩니다. 기본 단일 공백 이외의 필드 구분 기호를 사용하면 awk
7개가 아닌 8개의 열이 인식되며, 를 수행하면 마지막 열 오른쪽에 공백이 하나 이상 채워져 행 끝에 인쇄 { $1=$1; print; }
됩니다 .OFS
1다른 옵션(예: -i
, -e
, -m
)은 출력을 크게 변경합니다 ss
. 간결성과 명확성을 위해 우리는 이 정확한 명령에만 초점을 맞추겠습니다.
2근사치 이며 정확하지 않을 수 있습니다. 하지만 이는 이 질문/답변의 요점과 관련이 없습니다.
3물론 이는 보장되지 않으며 우리는 의도적으로 모든 드문 상황을 다루려고 시도하지 않습니다.
답변2
awk 필드 구분 기호가 일관되게 작동하지 않는 이유는 무엇입니까?
예, 신뢰할 수 없는 것은 출력의 공백 수입니다 ss
.
4열, 그것이 내가 원하는 것입니다.
그런 다음 헤더( -H
)를 제거하고 네 번째 열을 선택합니다.
$ ss -taH | awk '{print $4}'
172.31.19.34:22
[::ffff:172.31.19.34]:80
헤더는 고정되어 있으므로 필요한 경우 다시 추가하세요.
$ echo "Local Address:Port"
Local Address:Port
완전한 명령:
$ echo "Local Address:Port"; ss -tnH | awk '{print $4}'
Local Address:Port
172.31.19.34:22
[::ffff:172.31.19.34]:80
예, 컴퓨터에는 항상 IPv6 주소가 있습니다. 필요하지 않은 경우 IPv4 주소를 요청하세요.
$ ss -tnH4 | awk '{print $4}'
172.31.19.34:22