While each of Don Cragun's arguments holds true, just for the exercise I'm trying to infer the logics from your first post: field 4 is the link that glues together two records, of which field 2 is filled with "none1111" if the system did not have the correct value yet by the time of file creation. Both records need to be included at their original location in the file, and "none1111" needs to be replaced by the correct value found later in the same file for field 4. I'm sure there will be much more elegant solutions, but, as you are grepping several times, so do I. We need to run through the input file at least three times - a) to find the field 4 values, b) to find the field 2 values, and c) to replace. Step b) will be repeated for every pattern occurrence in the ifile. Here we go:
grep none1111 infile |
{ IFS=","; while read a b c d; do grep $d infile |
{ while read e f g h; do [ $f != 'none1111' ] &&
echo s/none1111\\\(.*$h\\\)/$f\\1/ >>sedfile; done;
}; done
}; sed -f sedfile infile; rm sedfile
Well, this one would remove the problem of repeated grep runs using xargs (whose known problem hopefully won't hit us in this case):
grep none1111 infile |
{ IFS=","; while read a b c d; do echo -n $d"|"; done; echo "#"; } |
xargs -I xy grep -E "xy" infile |
{ IFS=","; while read e f g h; do [ $f != 'none1111' ] && echo s/none1111\\\(.*$h\\\)/$f\\1/ >>sedfile; done; }
sed -f sedfile infile; rm sedfile
And, finally, a "oneliner" in which all parameters for sed are being created in a command substitution:
sed $(
grep none1111 infile | cut -d, -f4 | xargs -Ixy grep xy infile | cut -d, -f2,4 | grep -v none1111 |
sed 's/\(.*\),\(.*\)/-e s#none1111\\\(.*\\\)\2#\1\\1\2#/'
) infile
Like awk better? Try this:
awk 'BEGIN {FS=OFS=","}
{n = split($0, g); j++; for (i=1; i<=n; i++) h[j,i]=g}
! /none1111/ {f[$4]=$2}
END {for (i=1; i<=j; i++) print h[i,1], h[i,2]=="none1111" ? f[h[i,4]] : h[i,2], h[i,3], h[i,4]}
' infile