Description
  • Given a list whose members are separated by spaces.
  • If there are several instances of a given member, we want to keep only the first one and remove the others.
Raw Input
perl sed awk sed python ada c++ ruby sed c++ lisp
Desired Output
perl sed awk python ada c++ ruby lisp 
Script and Comments
Script1
[ 1] s/^/\n/
[ 2] :0
[ 3] s/\n( *[^ ]+)/\1\n/
[ 4] :1
[ 5] s/([^ ]+)\n(|.* )\1( +|$)/\1\n\2/
[ 6] t 1
[ 7] /\n *$/!b 0
[ 8] s/\n//
Comments
  1. This script divides a line into two parts: examined and non-examined one, and separates them with a newline character. Initially, the examined part is empty and the non-examined one consists the whole line.
  2. Then the following procedure repeats:
    • Move the first member from non-examined part to examined one (Step [3]).
    • Then remove from the non-examined part every instance of the same member (Steps [4] thru [6]).
  3. If you insert an `l' command before Step [5], the contents of PS before removing a redundant instance will be printed. The first seven output of command `l's are shown in the following, please place the mouse over each line to see the description:
    perl\n sed awk sed python ada c++ ruby sed c++ lisp$
    perl\n sed awk sed python ada c++ ruby sed c++ lisp$
    perl sed\n awk sed python ada c++ ruby sed c++ lisp$
    perl sed\n awk sed python ada c++ ruby c++ lisp$
    perl sed\n awk python ada c++ ruby c++ lisp$
    perl sed awk\n python ada c++ ruby c++ lisp$
    perl sed awk\n python ada c++ ruby c++ lisp$
  4. You may wonder why `t' of Step [6] still branches after sed's failure to remove a redundant `perl'. Although Step [5] failed, Step [3] succeeded (moving `perl' from non-examined part to examined one). Due to the characteristic of `t':
    t BRANCH
    branches to LABEL after a successful substitution since the last input line was read or conditional branch(`t') was taken.
    After reading the line and before Step [5], there was no conditional branch, but there was a successful substitution (Step [3])! Therefore, Step [3] branches! To eliminate redundant iterations of this kind, you may insert before Step [4] a `t' command: t 1.