LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Replace first 0 by 1 in specific column (https://www.linuxquestions.org/questions/linux-newbie-8/replace-first-0-by-1-in-specific-column-4175690855/)

karamunix 02-20-2021 10:08 AM

Replace first 0 by 1 in specific column
 
Hi Everyone,

I'm trying to replace in same file only the first 0 found in the fourth column by 1.

And to keep remaining 0 under the fourth column as is without any change.

To mention that columns are separated by a comma.

0,0,0,1
0,0,0,4
0,0,0,0
0,0,0,0
0,0,1,0
0,0,0,5
0,0,0,3
0,0,0,0
0,0,2,2


Desired output should be:
-------------------------

0,0,0,1
0,0,0,4
0,0,0,1 --> Here the 0 in the third row for the fourth column was replaced by 1.
0,0,0,0 --> Here the 0 should not be changed.
0,0,1,0
0,0,0,5
0,0,0,3
0,0,0,0
0,0,2,2


If we run the script another time:
----------------------------------
Desired output should be:
-------------------------

0,0,0,1
0,0,0,4
0,0,0,1
0,0,0,1 --> Here the 0 was replaced by 1 this time and so on.
0,0,1,0
0,0,0,5
0,0,0,3
0,0,0,0
0,0,2,2

Any help would be very appreciated.

Thanks in advance.

Turbocapitalist 02-20-2021 10:14 AM

Welcome. This looks like an easy task for AWK or perl. In either case, just set the input field separator to a comma. See -F for FS in AWK, or -a for autosplit in perl. (Edit: in AWK, the variables FS and OFS might help also.)

What have you tried so far, and where are you stuck? Which distro is this for?

computersavvy 02-20-2021 12:52 PM

Another candidate to solve this would be sed.

shruggy 02-20-2021 01:01 PM

@computersavvy. Yes, but changing an arbitrary field with sed is not as convenient as with awk. Unless like in the example posted by OP this happens to be the last field in the line: then doing it with sed would be quite easy indeed.

JeremyBoden 02-20-2021 04:51 PM

Who invents these artificial "problems"?

MadeInGermany 02-21-2021 07:31 AM

If it's always the last field then it's easy (though not trivial) with GNU sed:
Code:

sed -i '0,/,0$/ s//,1/' filename
But if you want to handle any given field, then it's nearly impossible with sed.
With perl (as suggested, the -F option splits to @F):
Code:

perl -i -F"," -le 'BEGIN { $f=3; $,=","; $d=0; } $F[$f] eq "0" and !$d++ and $F[$f]="1"; print @F;' filename
The same with awk; lacking a -i option, its output goes to a temporary file:
Code:

file=filename
awk -F"," 'BEGIN { f=4; OFS="," } { $f == "0" && !d++ && $f="1"; print }' "$file" >"$file".new &&
mv "$file".new "$file"


shruggy 02-21-2021 08:48 AM

Starting with version 4.1.0, GNU awk even provides the in-place file editing functionality:
Code:

gawk -F, -vOFS=, -vf=4 -i inplace '!d&&!$f{$f=d=1}1' filename


All times are GMT -5. The time now is 10:39 PM.