0

Sample file:

11:34:21.590434 IP 10.10.1.30 > 10.10.1.217: ICMP echo reply, id 27948, seq 1, length 64

In Python, it's easy to identify the number of field by using enumerate function. E.g.

>>> i = '11:34:21.590434 IP 10.10.1.30 > 10.10.1.217: ICMP echo reply, id 27948, seq 1, length 64'
>>> 

Split the string

>>> i.split()
['11:34:21.590434', 'IP', '10.10.1.30', '>', '10.10.1.217:', 'ICMP', 'echo', 'reply,', 'id', '27948,', 'seq', '1,', 'length', '64']
>>> 

Put it on new variable, let say j

>>> j = i.split()
>>> 

Enumerate it

>>> 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')
>>> 

So, if I want to print out the source IP which is field number 3 with awk, it's so easy rather than to identify it manually with naked eyes.

wolf@linux:~$ awk '{print $3}' file.txt 
10.10.1.30
wolf@linux:~$ 

I know it's possible to do similar thing in Linux/Bash, I just can't figure it out yet.

Update

I know it's easy to get the number of column by using NF

wolf@linux:~$ awk '{ print NF }' file.txt
14
wolf@linux:~$ 

But what I want to achieve here is to identify each column and it's numbers. Probably something similar like Python enumerate output.

1
2

You can enumerate the fields using AWK:

awk '{ for (i = 1; i <= NF; i++) print i, $i }' file.txt

or with tr and nl:

tr ' ' '\n' < file.txt | nl

(Filter through head -n1 first if you want to stop at the end of the first line with tr; otherwise fields will be counted across lines.)

You can also find this out using Bash arrays (depending on IFS):

arr=($(head -n1 file.txt))
i=0
while [[ i -lt ${#arr[@]} ]]; do
    printf "%d %s\n" $((i+1)) "${arr[$i]}"
    ((i++))
done
0
2

Hope this helps

$ tr ' ' '\n' < 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
$ 

or

$ read -ab < file.txt 
$ for c in ${b[*]}; do echo $c; done | 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
$ 
0
1

With GNU awk for multi-char RS and \s shorthand for [[: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

It assumes you only have 1 line in your input just like in the example in your question.

2
  • Thanks, but I did not get similar output ... wolf@linux:~$ awk -v RS='\\s+' '{print NR, $0}' file.txt 1 11:34:21.590434 IP 10.10.1.30 > 10.10.1.217: ICMP echo reply, id 27948, 2 eq 1, length 64 wolf@linux:~$ echo $SHELL /bin/bash wolf@linux:~$ – Wolf Jan 31 at 17:03
  • Then you copy/pasted wrong, or you aren't using gawk as the answer says is required, or your input doesn't look like the line you posted. If you use the script I posted on the input you posted using gawk as I said is required then you WILL get the output I posted. – Ed Morton Jan 31 at 17:18
1

Solution with 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
       
$ 
0

I guessed there are not any right solution rather than Stephen Kitt. but if you only need IP Addrerss you could use below

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
0

grep out the fields and lay them one per line. Then number them with grep's -n option.

echo "....." |
grep -Po  '\S+' | grep -n ^ | sed 's/:/ /'

or

cat file.txt | grep -Po  '\S+' | grep -n ^ | sed 's/:/ /'

For perls more recent than 5.14.4

perl -lane '
  while (my($i,$e) = each @F) { print "$i $e"; }
' file.input

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.