サンプルファイル:
11:34:21.590434 IP 10.10.1.30 > 10.10.1.217: ICMP echo reply, id 27948, seq 1, length 64
Pythonでは、列挙関数を使用してフィールド数を簡単に識別できます。例えば
>>> i = '11:34:21.590434 IP 10.10.1.30 > 10.10.1.217: ICMP echo reply, id 27948, seq 1, length 64'
>>>
文字列分割
>>> i.split()
['11:34:21.590434', 'IP', '10.10.1.30', '>', '10.10.1.217:', 'ICMP', 'echo', 'reply,', 'id', '27948,', 'seq', '1,', 'length', '64']
>>>
新しい変数に入れます。j
>>> j = i.split()
>>>
数える
>>> for i in enumerate(j, 1): i
...
(1, '11:34:21.590434')
(2, 'IP')
(3, '10.10.1.30')
(4, '>')
(5, '10.10.1.217:')
(6, 'ICMP')
(7, 'echo')
(8, 'reply,')
(9, 'id')
(10, '27948,')
(11, 'seq')
(12, '1,')
(13, 'length')
(14, '64')
>>>
したがって、awkを使用してフィールド3のソースIPを印刷するには、肉眼で手動で識別するよりも簡単です。
wolf@linux:~$ awk '{print $3}' file.txt
10.10.1.30
wolf@linux:~$
Linux / Bashで同様のことを行うことが可能であることを知っていますが、まだ把握していません。
修正する
私は以下を使用して列数を取得するのが簡単であることを知っています。NF
wolf@linux:~$ awk '{ print NF }' file.txt
14
wolf@linux:~$
しかし、ここで達成したいのは、各列とその番号を識別することです。 Pythonの列挙型出力に似ている可能性があります。
答え1
AWK を使用してフィールドを列挙できます。
awk '{ for (i = 1; i <= NF; i++) print i, $i }' file.txt
または:tr
nl
tr ' ' '\n' < file.txt | nl
(head -n1
最初の行の終わりに停止を使用するには、まずフィルタリングしてくださいtr
。そうしないと、フィールドは複数の行にわたって計算されます。)
Bash配列を使用してこれを見つけることもできます(によって異なりますIFS
)。
arr=($(head -n1 file.txt))
i=0
while [[ i -lt ${#arr[@]} ]]; do
printf "%d %s\n" $((i+1)) "${arr[$i]}"
((i++))
done
答え2
複数文字RS
と\s
略語でGNU awkを使用する[[:space:]]
:
$ awk -v RS='\\s+' '{print NR, $0}' file
1 11:34:21.590434
2 IP
3 10.10.1.30
4 >
5 10.10.1.217:
6 ICMP
7 echo
8 reply,
9 id
10 27948,
11 seq
12 1,
13 length
14 64
質問の例のように、入力に行が1つしかないとします。
答え3
代わりに正しい解決策がないと思います。スティーブンジッタ。しかし、必要な場合IPアドレス以下を使用できます。
tr ' ' '\n' <<<'11:34:21.590434 IP 10.10.1.30 > 10.10.1.217: ICMP echo reply, id 27948, seq 1, length 64' | grep IP -A1 | grep -v IP
答え4
ソリューションsed
$ sed -n '/1/{s/ /\n/g;p}' < file.txt | nl
1 11:34:21.590434
2 IP
3 10.10.1.30
4 >
5 10.10.1.217:
6 ICMP
7 echo
8 reply,
9 id
10 27948,
11 seq
12 1,
13 length
14 64
$