Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there any way to subtract one column of data containing text from another column containing text and get third column containing unique charcters, for example using awk eg.


ab   a
cd   d    
efg  ef

desired output:

ab   a   b
cd   d   c
efg  ef  g
share|improve this question

Yes, awk is a suitable choice:

awk 'NF{t=$1;gsub("["$2"]","",t);print$0,t}' input

In case the second field may contain characters with special meaning in regular expression character classes, those have to be escaped. Solving that in POSIX awk is lengthy, so I post the GNU awk alternative only:

gawk 'NF{print$0,gensub("["gensub(/([\[\]^-])/,"\\\\\\1","g",$2)"]","","g",$1)}' input
share|improve this answer
Great that works well, however for me it takes into account position in first column so that there is an output only if character differs at first position (left hand position) in column 1.....am I doing something wrong?? – alex Jun 12 '12 at 14:17
Ah yes my mistake.............works now!!! Thank you kindly. – alex Jun 12 '12 at 14:22

Manatworks solution is of course fine. This is just a pure bash alternative.

while read line
  in=${line/ */}
  pat=${line/* /}
  echo $line ${in/$pat}
done < aba.dat

ab a b
cd d c
efg ef g
  • In in replace (/) from $line what is a blank, followed by something - not in regex, but globbing style.
  • In pat it is the opposite: remove what is before the blank. Removing, because the replacement part of ${src/pattern/replacement} is blank.
  • ${in/$pat} replaces pat in in with nothing. The pat var needs to be marked as variable $ in contrast to the first variable/part (in).
share|improve this answer
If you don't care about preserving the amount of whitespace between the existing columns: while read -r in pat; do echo "$in $pat ${in/$pat}"; done – Gilles Jun 12 '12 at 22:28

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.