Reputation: 2077
I would like to make zero the entire row except first column, if it has a zero value in any other column. e.g.,
ifile.txt
1 4.5 9
2 5.0 0
3 2.4 4
4 3.1 2
5 0.0 0
6 2.4 1
7 0.0 5
I am looking my output as
ofile.txt
1 4.5 9
2 0.0 0
3 2.4 4
4 3.1 2
5 0.0 0
6 2.4 1
7 0.0 0
Upvotes: 0
Views: 214
Reputation: 1307
This achieves your desired outcome, while preserving white space:
gawk '!($2*$3) {$0 = gensub(/([[:space:].])[0-9]/,"\\10", "g")} 1' ifile.txt
Explanation:
!($2*$3)
: If one of the 2nd or 3rd fields is zero (0) then their product will be zero[0-9]
which come after a space or dot [[:space:].]
with zero (0)\\10
: is actually \1
+ 0
: meaning print the first match (the space or dot), followed by a literal zero (0)If you want to make it work for an arbitrary number of fields, e.g. for the following input:
$ cat ifile_ext.txt
1 4.5 3.2 .5 1.9 2.0 9
2 5.0 6.4 .1 0.0 3.4 0
3 2.4 4.1 .4 2.3 1.0 4
4 3.1 2.0 .6 1.3 2.4 2
5 0.0 1.0 .9 2.3 0.0 0
6 2.4 2.0 .1 4.5 1.2 1
7 0.0 4.5 .2 9.4 0.0 5
8 1.0 2.0 .0 1.2 4.1 1
Then you have to loop over the fields, and then perform the same transformation:
gawk '{ for(i=2;i<=NF;i++) if (!$i) {$0 = gensub(/([[:space:].])[0-9]/,"\\10", "g")} } 1' ifile_ext.txt
Output:
1 4.5 3.2 .5 1.9 2.0 9
2 0.0 0.0 .0 0.0 0.0 0
3 2.4 4.1 .4 2.3 1.0 4
4 3.1 2.0 .6 1.3 2.4 2
5 0.0 0.0 .0 0.0 0.0 0
6 2.4 2.0 .1 4.5 1.2 1
7 0.0 0.0 .0 0.0 0.0 0
8 0.0 0.0 .0 0.0 0.0 0
Upvotes: 1
Reputation: 10039
sed 's/$/ /;/[[:space:]]\(0\.\)\{0,1\}0[[:space:]]/!b o
s/\([^[:space:]]*\).*/\1 0.0 0/
:o
s/ $//' YourFile
with formating column
sed 's/$/ /;/[[:space:]]\(0\.\)\{0,1\}0[[:space:]]/!b o
h;s/[[:space:]].*//;x;s/[^[:space:]]*//;s/[1-9]/0/g;H;x;s/\n//
:o
s/ $//' YourFile
Upvotes: 1
Reputation: 204731
$ awk '!$2{$3=0} !$3{$2="0.0"} 1' file
1 4.5 9
2 0.0 0
3 2.4 4
4 3.1 2
5 0.0 0
6 2.4 1
7 0.0 0
Upvotes: 3
Reputation: 36146
Using bash (and bc) and for an arbitrary number of columns:
#!/bin/bash
IFS=$'\n'
for line in $(cat in.txt)
do
found_zero=
zeros=
IFS=$' '
# Find if zero in any column, and generate columns with zeros
for e in ${line#* }
do
(( $(bc <<< "$e == 0.0") == 1 )) && found_zero=1
zeros="$zeros 0.0"
done
# If found zero in a column, write only zeros
if [ $found_zero ]
then
echo "${line%% *}$zeros"
else
echo $line
fi
done
Upvotes: 1
Reputation: 5861
Assuming the columns in your input file are separated by tabs:
awk -F'\t' '{ if ($2 == 0 || $3 == 0) { $2 = 0; $3 = 0 }; printf("%d\t%.1f\t%d\n", $1, $2, $3) }' ifile.txt
Output:
1 4.5 9
2 0.0 0
3 2.4 4
4 3.1 2
5 0.0 0
6 2.4 1
7 0.0 0
Upvotes: 4