How can we do this!?

Hi,

I have an input file which looks like

101,103,1,2,3
,,,2,3
,,,4,5
201,234,7,8,9
,,,4,5

I would like top have output like, Is this possible?

101,103,1,2,3
101,103,1,2,3
101,103,1,4,5
201,234,7,8,9
201,234,7,4,5

Thanks a lot,

Looks like there's a comma too many in the lines with missing elements. Assuming this is an error, try

awk '!$1{$1=OLD1} !$2{$2=OLD2} {OLD1=$1; OLD2=$2} 1' FS="," OFS="," file
101,103,1,2
101,103,2,3
101,103,4,5
201,234,8,9
201,234,4,5
1 Like

Thanks a lot Rudi. You are right, the input file was wrong. i have corrected it now. Will this code of yours even work now if i just include

$3=OLD3

in your code.

You're half way there. Post the full solution, and we'll comment on it.

Hi RudiC,

Will this code work?. Just included $3 component in your logic.

awk '!$1{$1=OLD1} !$2{$2=OLD2} !$3{$3=OLD3} {OLD1=$1; OLD2=$2; $3=OLD3} 1' FS="," OFS="," file 

Thanks

Hello Indra2011,

Good try :b:, a little adjustment to your solution will be, don't change $3 because it will make it's value to variable as OLD3 which will be dangerous on the first line itself when variable OLD3 will be NULL and it will be assigned to 3rd column, then it will never be a NON-NULL value, so try.

awk '!$1{$1=OLD1} !$2{$2=OLD2} !$3{$3=OLD3} {OLD1=$1; OLD2=$2; OLD3=$3} 1' FS="," OFS=","  Input_file

Thanks,
R. Singh

1 Like

Hi Ravinder Singh,

I am getting a syntax error. Also, my error look like this

awk: file{$1=OLD1} file{$2=OLD2} file{$3=OLD3} {OLD1=$1; OLD2=$2; OLD3=$3} 1 
awk : ^ syntax error

Please suggest, how can I correct it . is it due to

1' file

Thanks

Hello Indra2011,

Not sure what's going on it is working fine for me, could you please try following things.

I- Check if there are any carriage characters are present or not in your Input_file by doing cat -v Input_file . If yes then remove them by adding gsub(/\r/,"") in starting of my previous post's solution.

II- If no carriage characters, then ,my second guess would be are you using Sun OS/Solaris? If yes then, on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk .

Let me know how it goes then.

Thanks,
R. Singh

1 Like

Thanks R.Singh. It did not work.

Is there any other way we can do this by reading the input file first --

something like --

cat Input_File | awk "Your and Rudi's logic" 

.

Thanks

Hello Indra2011,

awk could read any Input_file by its own no need to use cat here.
You have to show us the complete console output like what's going on there, without that we could only guess.

Also I am coming with this function approach for this question, where you could just mention like how many columns you want to verify.
Following is the code on same too:

1st Scenario: with your asked query.

awk -F, 'function check(val){do{;num=split(val, array,",");i=1;while(i<=num){if(!$array){$array=old;} else {old=$array};;i++};i="";print $0;;} while((getline)>0)}; check("1,2,3")' OFS=,   Input_file

2nd scenario: Input_file which I have created for checking purposes, a test file

##Input_file:
cat  Input_file
101,103,1,2,3
,,,2,3
,,,4,5
201,234,7,8,9
,,,4,5
,,,,5
  
awk -F, 'function check(val){do{;num=split(val, array,",");i=1;while(i<=num){if(!$array){$array=old;} else {old=$array};i++};i="";print $0;;} while((getline)>0)}; check("1,2,3,4")' OFS=,   Input_file

In this above code I have provided 1,2,3,4 fields so it will look for 1st, 2nd, 3rd and 4th fields here. Kindly do check the same and let me know if you have any queries.

EDIT: Adding a NON-one liner form of solution too successfully now.

awk -F, 'function check(val){
                                do{
                                        num=split(val, array,",");
                                        i=1;
                                        while(i<=num){
                                                        if(!$array){
                                                                                $array=old;
                                                                      }
                                                        else          {
                                                                                old=$array
                                                                      }
                                                                                i++
                                                     }
                                        i="";
                                        print
                                  }
                                while((getline)>0)
                            };
         check("1,2,3,4")
       ' OFS=,         Input_file

EDIT2: In above code you could change from !$array to $array == "" in case your Input_file may have zero too in any of the columns.

Thanks,
R. Singh

Did any of the proposals given in this thread run error free? If yes, what did you change in post#7? If no, please post your command and its stdin and stderr output exactly as is, one to one, char by char, so we have a chance to analyse.

Hi Ravinder,

Many many thanks for help. This was what I get while running the code.

disco,mum $ awk '!$1{$1=OLD1} !$2{$2=OLD2} !$3{$3=OLD3} {OLD1=$1; OLD2=$2; OLD3=$3} 1' FS="," OFS="," test

awk 'test1{$1=OLD1} test2{$2=OLD2} test3{$3=OLD3} {OLD1=$1; OLD2=$2; OLD3=$3} 1' FS="," OFS="," test
101,103,1,2,3
,,,2,3
,,,4,5
201,234,7,8,9
,,,4,5

Thanks

What's your OS and shell?

1 Like

Hello Indra2011,

I haven't seen your second command in any of the solutions provided in this thread?
It will NOT give any results as variables named test1, test2, test3 are never having values.

Could you please try my code(s) in POST#10 and let us know how it goes then?

Thanks,
R. Singh

1 Like

Linux and csh.

---------- Post updated at 02:17 AM ---------- Previous update was at 02:14 AM ----------

Second command is not the one I am giving. It is the getting displayed once I run your's command. I don't know how

!$

is every time replaced by

test

.

Looks like !$ has a special meaning in csh , even if showing up within single quotes. As I don't have any knowledge on csh , I'll have to stop my attempts to help.

Many many thanks. RudiC and Ravinder, I tried your command with changing the shell to bash and it worked.

... gnash ...

Shamelessly stealing RavinderSingh13's idea, I managed to compose this:

awk '
NR == 1 {for (n = split (CHK, T); n>0; n--) C[T[n]] 
        }
        {for (c in C) if (!$c) $c = OLD[c]
         split ($0, OLD)
        }
1
' FS="," OFS="," CHK="2,4" file

Would this work?

perl -nlaF, -e '$,=","; for(0..$#F){$p[$_]=$F[$_]if$F[$_]} print @p' indra2011.example
101,103,1,2,3
101,103,1,2,3
101,103,1,4,5
201,234,7,8,9
201,234,7,4,5

As it is, it does, because it is part of csh s commandline-editing.

I hope this helps.

bakunin

/PS: I forgot to add: the exclamation mark needs to be escaped in csh even in strong quoting (single quotes).