How to update field value in place?

Dear all:

I have a file:

1:00    2:abc   3:12aswe

and I ran the following awk script on this file:

#!/usr/bin/awk -f
{ i= 1;
while(i<=NF)    {
                $i=substr($i, 1, index($i, ":")-1);
                i++
                }
}

I am expecting the file would become (after running the script):

1 2 3

However, it didn't. How should I change the code to make it work?

Awk is a filter, it doesn't modify the input. You should redirect into a temporary file, then overwrite the original.
How about:

cp $input ${input}.copy
awk -F: '{print $1}' RS="[ \t]+" ORS=" " $input > ${input}.tmp
mv ${input}.tmp $input
1 Like

Another method:

awk '{ gsub(/:[^ ]*/,x); $1=$1 }1' input_file > input_file.tmp

mv input_file.tmp input_file 
1 Like

There is no default print if the main loop consists of only {}
You must add a print command. Lazy people do a 1 , that's a true condition where the default action is again a print.
For demonstration I added all three possible print commands.

#!/usr/bin/awk -f
{ i= 1;
while(i<=NF)    {
                $i=substr($i, 1, index($i, ":")-1);
                i++
                }
print
}
{print}
1
1 Like

Thank you very much.

By the way, can perl update the field value in place? thanks.

Yes, perl -i ... does it.
Here perl seems to be preferable anyway.

perl -pe 's/:\S*//g' file
1 Like

With perl you can specify a backup extension after the -i switch:

perl -i.bak 's/:\S*//g' file #will save the original as file.bak

GNU sed can also edit in-place, here is sed solution:

sed -i 's/:[^ \t]*//g' 
1 Like

Thank you very much.