awkとssの出力を使用して4番目の列を印刷しようとしています。時にはうまくいきますが、時には列を誤ってマージしたり分割したりすることがあります。いくつかの異なるFSオプションを試しましたが、これにはフィールドヘッダーにスペースが含まれているため、2つ以上のスペースがあります。
これにより、5番目の列と空のヘッダーが提供されます。
$ 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
ここで同じコマンドを使用すると、私が望む4番目の列が提供されます。
$ 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
、、、、、、、、です。4番目と5番目の列はコロン()で区切られています。 6番目と7番目の列も同じです。他のすべてのコンテンツはスペース文字で区切られます。 すべての列は、ソートが必要なスペースで埋められます。 4番目と6番目のパディングは左側にあり、他のすべてのパディングは右側にあります。Recv-Q
Send-Q
Local Address
Port
Peer Address
Port
:
追加のパディングが発生する可能性があります。
出力が
ss -nt
端末に渡される場合:その行の最小長(各フィールドの最長内容と最小間隔(6文字)の合計として計算されます)が端末幅より小さい場合、各行は均等にパディングされて端末幅に拡張されます。スペースがあるすべての列。
それ以外の場合、行は破棄され、フィールドは行に沿って並べ替えられます(上記のように端子の幅まで埋められます)。
出力が
ss -nt
端末に渡されない場合(たとえば、通常のファイルにパイプまたはリダイレクトされる場合)、行の実際の長さは少なくとも80の倍数で定義され、これは上記で定義された最小長よりも高くなります。すべての列は、合計行長(80、160、240、...文字2)を達成するために空白で均等に埋められます。
したがって、2つの列が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
'
これにより、コロンで区切られた4番目と5番目の列(ローカルアドレスとポート)のみが印刷されます。デフォルトの単一の空白以外のフィールド区切り文字を使用すると、awk
7つではなく8つの列が認識され、これを実行すると、最後の列の右側に1つ以上の空白が埋められ、行の末尾に印刷され{ $1=$1; print; }
ます。OFS
1他のオプション(例えば、、、-i
)-e
は-m
出力を大幅に変更しますss
。簡潔さと明確さのために、私たちはこの正確な命令に焦点を当てます。
2近似であり、正確ではない可能性があります。ただし、これはこの質問/回答の要点とは関係ありません。
3もちろん、これは保証されておらず、私たちは意図的にすべてのまれな状況に対処しようとしません。
答え2
awkフィールド区切り文字が一貫して機能しないのはなぜですか?
はい、信頼できないのは出力の空白の数ですss
。
4列、それが私が望むものです。
次にヘッダー(-H
)を削除し、4番目の列を選択します。
$ 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