awk -sed help : forth . to convert to "space"

Hi Experts,
Good day,

I am looking for the 6th fields 4th dot (.) to convert into a space in the output.

file:

tcp        0      0  10.80.110.100 2900     1 10.40.104.6.42769     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.103.7.38620     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.101.8.11764     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.102.9.49338     ESTABLISHED
  • Desired output to be:
tcp        0      0  10.80.110.100 2900     1 10.40.104.6 42769     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.103.7 38620     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.101.8 11764     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.102.9 49338     ESTABLISHED

Thank a lot...

If it's a small file, then a very simple ksh version may be sufficient:-

while read type count1 count2 local port other remote state
do
  echo "$type $count1 $count2 $local $port $other ${remote%.*} ${remote##*.} $other"
done < inputfile > outputfile

You can format the column width with typeset commands if you wish.

The variable substitution with $remote is as follows:-
${remote%.} says to remove everything from end of $remote at the shortest length that matches a dot, i.e. you get the first four parts.
${remote##
.} says to remove everything from start of $remote at the longest length that matches a dot, i.e. you are left with the last part.

I hope that this helps.

Robin
Liverpool/Blackburn
UK

you may try

$ cat test
tcp        0      0  10.80.110.100 2900     1 10.40.104.6.42769     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.103.7.38620     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.101.8.11764     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.102.9.49338     ESTABLISHED
awk  -F"." '{for(i=1;i<=NF;i++)printf (i==7)? $i OFS : (i<NF)?$i FS:$i;printf RS}' test

resulting

tcp        0      0  10.80.110.100 2900     1 10.40.104.6 42769     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.103.7 38620     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.101.8 11764     ESTABLISHED
tcp        0      0  10.80.110.100 2900     1 10.40.102.9 49338     ESTABLISHED
3 Likes

Hi Akshay,

Could you please explain also this. I will be grateful to you.

Thanks,
R. Singh

FS="." ---> Field separator is dot (.)
for(i=1;i<=NF;i++) ---> start loop from 1st Field to 8th Field
(i==7)? ---> If field is 7th one then print $7 and Output separator (OFS) by default output separator is set to space, else check field is less than 8 (i<NF)? , if yes print column and field separator that is dot(.) . if field is greater than 7 then just print column, once loop completes print newline that is RS (Row separator)

Hello Akshay,

When code will get the value for 7th column, then I have query if we are setting the OFS to default which is space then how it is putting space at the last

.(dot)

not between every

.(dot)

I mean it should be like as

10 40 104 6 4276 

could please explain?

Thanks,
R. Singh

Another way with sed :

sed 's/\.\([^.]*\)$/ \1/' file

or

sed 's/\./ /7' file
2 Likes

Hope this will be helpful

$ awk -F"." '{print NF}' test
8
8
8
8

This is when FS is dot(.)

$ awk -F"." '{for(i=1;i<=NF;i++)printf $i"-->col"i OFS;printf RS}' test
tcp        0      0  10-->col1 80-->col2 110-->col3 100 2900     1 10-->col4 40-->col5 104-->col6 6-->col7 42769     ESTABLISHED-->col8 
tcp        0      0  10-->col1 80-->col2 110-->col3 100 2900     1 10-->col4 40-->col5 103-->col6 7-->col7 38620     ESTABLISHED-->col8 
tcp        0      0  10-->col1 80-->col2 110-->col3 100 2900     1 10-->col4 40-->col5 101-->col6 8-->col7 11764     ESTABLISHED-->col8 
tcp        0      0  10-->col1 80-->col2 110-->col3 100 2900     1 10-->col4 40-->col5 102-->col6 9-->col7 49338     ESTABLISHED-->col8 

this is when FS is default

$ awk '{for(i=1;i<=NF;i++)printf $i"-->col"i OFS;printf RS}' test
tcp-->col1 0-->col2 0-->col3 10.80.110.100-->col4 2900-->col5 1-->col6 10.40.104.6.42769-->col7 ESTABLISHED-->col8 
tcp-->col1 0-->col2 0-->col3 10.80.110.100-->col4 2900-->col5 1-->col6 10.40.103.7.38620-->col7 ESTABLISHED-->col8 
tcp-->col1 0-->col2 0-->col3 10.80.110.100-->col4 2900-->col5 1-->col6 10.40.101.8.11764-->col7 ESTABLISHED-->col8 
tcp-->col1 0-->col2 0-->col3 10.80.110.100-->col4 2900-->col5 1-->col6 10.40.102.9.49338-->col7 ESTABLISHED-->col8

---------- Post updated at 01:12 PM ---------- Previous update was at 01:08 PM ----------

---------- Post updated at 01:13 PM ---------- Previous update was at 01:12 PM ----------

Thanks a lot Akshay for explaining me, it really helped.

Welcome

Like this simple approach : I was missing.

sed 's/\./ /7' file

Scrutinizer, thanks a lot ,

Hello,

One more solution for same.

awk '{for(i=0;i<=NF;i++)
{
if(i==7)
{match($i,/..\...\....\..\....../); {$i=substr($i,RSTART,RLENGTH-6) " " substr($i,RSTART+12,RLENGTH)};}
}} 
1' file_name

Output will be as follows.

tcp 0 0 10.80.110.100 2900 1 10.40.104.6 42769 ESTABLISHED
tcp 0 0 10.80.110.100 2900 1 10.40.103.7 38620 ESTABLISHED
tcp 0 0 10.80.110.100 2900 1 10.40.101.8 11764 ESTABLISHED
tcp 0 0 10.80.110.100 2900 1 10.40.102.9 49338 ESTABLISHED

Thanks,
R. Singh