If preserving the order of the input lines is important, then a single associative array is not enough (because associative arrays are inherently unordered in most languages, including awk and perl), so you need two arrays.
- an array with numeric indexes containing the text of the input lines
- an associative array containing the line number of the first array that matches the hash.
This is much easier to do in perl than in awk, so that's what I'll use. I'll use @lines for the first array, and %keys for the second.
@F is the name of the automatically-created array containing the auto-split fields when the -F option is used - similar to awk's $1, $2, $3 etc, except that it's $F[0], $F[1], $F[2], etc. and $F[-1] is the last element of @F, roughly equivalent to awk's $NF. Note that perl arrays start from 0, not 1.
perl -F'\)' -l -e '
$key = join(")",@F[0..$#F-1]);
if ($F[-1] eq "ADD") {
$lines[$.] = $_; # $. is the line number of the current file
$keys{$key} = $.;
} elsif ($F[-1] eq "REM") {
delete($lines[$keys{$key}]);
delete($keys{$key});
}
if (eof) {
foreach $l (@lines) { print $l if $l; };
@lines = ();
%keys = ();
};' inputfile
Output:
23445)HGT6787)1)ADD
67894)OIY5678)0)ADD
12345)OIY5678)0)ADD
12345)X678GHR)1)ADD
Note that this perl version works with any number of fields in the input, it isn't hard-coded to use fields 1-3 for the data and field 4 for the "ADD" or "REM" instruction. Instead, it uses all but the last field for the data and the last field for the instruction. This is possible to do with awk too, but you'll need to write a join() function or at least a simple loop to concatenate all but the last field.
This perl version is also capable of processing multiple input files, by detecting the end of each file (using the eof() function), and clearing both arrays after printing the lines which haven't been deleted. i.e. it resets everything at the end of each input file. I could have just used an END {} block as in @steeldriver's awk answer, but this seemed appropriate because you never know when you're going to want to re-use a script in a slightly different way...and it's always a good idea to ask yourself "what if?" and "how could this fail?" type questions.
)as the field sep, then show that.