I want to replace the '1' from the first row with the value given in the second row. Here is the input dataset:
0,0,1,1,0,0,1,1,0,1,0,1,0,1
65,70,75,80,85,85,90
Desired output:
0,0,65,70,0,0,75,80,0,85,0,85,0,90
Thanks in advance.
Like this (any awk):
$ tac file | awk '
BEGIN{FS=OFS=","}
NR==1{split($0, a, FS);next}
NR==2{for (i=1; i<=NF; i++)
if ($i == 1) $i=a[++c]}
1 # aka print
'
Replace tac file by tail -r file on *BSD
0,0,65,70,0,0,75,80,0,85,0,85,0,90
Using GNU sed
$ sed -Ez ':a;s/([^,]*)1\>(,?[^\n]*\n)([0-9]+)(,|\n)/\1\3\2/;ta' input_file
0,0,65,70,0,0,75,80,0,85,0,85,0,90
70 to 15 or 21.
I like @GillesQuenot's answer, but here's an alternative using perl that doesn't need tac or tail -r.
Instead, it uses three arrays - one for the first input line (@l), one for the second line (@a), and the third for output (@o). It does the printing in the END block:
$ perl -F, -le '
if ($.==1) { @l = @F };
if ($.==2) { @a = @F };
END {
foreach $i (0..$#l) {
push @o, $l[$i] == 1 ? $a[$c++] : $l[$i]
};
print join("," , @o)
}' input.txt
0,0,65,70,0,0,75,80,0,85,0,85,0,90
BTW, perl's -F option automatically enables perl's -a (auto-split to an array called @F) and -n (iterate over input like sed -n or awk) options. -l enables automatic handling of line-ending chars (e.g. newlines).
You could do something similar with awk, but you'd probably have to write a join() function (which is built-in to perl).