This works only if Count[u, 0] === Count[v, 0]
sz = 20;
u = RandomInteger[{1, sz}, sz] (zeros = RandomInteger[1, sz])
v = RandomInteger[{1, sz}, sz] RandomSample[zeros]
res = u[[Ordering[Sign[u]][[Ordering[Ordering[Sign[v]]]]]]]
If Count[u, 0] > Count[v, 0], I find it most intuitive to match/reposition the first Count[v, 0] zeros of u while keeping the remaining zeros in place, and when Count[u, 0] < Count[v, 0] to match all zeros of u with the first Count[u, 0] zeros of v. E.g.
u = {2,3,0,0}; v = {4,0,1,6} yields {2,0,3,0} and
u = {2,3,1,0}; v = {4,0,0,6} yields {2,0,3,1} or in code:
Evaluate[PadRight[DeleteCases[Insert[u[[Ordering[-Sign[u]]]],
#, # - Range[0, Length[#] - 1] &[Take[Position[v, 0, {1}],
UpTo[Count[u, 0]]]]], 0], Length[v], 0]] &[0]
For all cases if u and v contain negative numbers, you need to replace Sign by Abs@*Sign