This should get you started. My lunch break is almost over so I can't do it all for you, but it'll help with the automation:
That returns a list of selection sets, the first one being all blocks with a name that begins with "X_", and so on. You can make the list as long as you'd like.
(mapcar '(lambda (x) (ssget "X" (list (cons 2 x)))) (list "X_*" "APOINT_*"))
Alls you need is to loop through and do something with each selection set, like a block replace.
Good luck, I'm sure you've got enough smarts to figure out the rest, if you've come so far already. ^.^
EDIT: And before anyone "corrects" me, yes, you could probably just extend the Lambda to include the block replace. I just don't have the time.
EDIT EDIT: Meh..
See if this works, it's untested. It'll insert the correct block at the same insertion point of the incorrect block, then delete the incorrect one. At least, that's the idea. My fingers are crossed.
(defun c:test( / ss entSet)
(mapcar '(lambda (x)
(setq ss (ssget "X" (list (cons 2 (strcat x "_*")))))
(setq entSet (vl-remove-if-not '(lambda (y) (= (type (cadr y)) 'ENAME)) (ssnamex ss)))
(mapcar '(lambda (z) (vl-cmdf "-insert" x (cdr (assoc 10 (entget z))) "" "" "" "erase" z "")) entSet)
(list "X" "APOINT"))