Python script
Change the path on line 3 src_file = "E:/tempmymat.blend"
import bpy src_file = "E:/tempmymat.blend" D = bpy.data def main(): # find materials that you want to replace bad_mats = {m.name:m for m in D.materials if not m.library} # load materials to replace with with D.libraries.load(src_file, link=True) as (src, me): me.materials = [name for name in src.materials if name in bad_mats] # create copies of the loaded file's materials, rename them and store # a convenient dictionary pointing from old materials to new materials replacements = {} for m in me.materials: new_mat = m.copy() bad_mat = bad_mats[m.name] new_mat.name = m.name replacements[bad_mat] = new_mat # find old materials and replace with new materials for o in D.objects: for slot in o.material_slots: replacement = replacements.get(slot.material) if replacement: slot.material = replacement # unlink old materials and the external file (library) for m in bad_mats.values(): D.materials.remove(m) D.libraries.remove(D.libraries[-1]) main()
if not m.library is used on the first line of main() in order to ensure there's a single material with each name. If you need to make it work with materials linked to other files also being replaced, remove that condition. If you're worried that as a result you can indeed get multiple materials with the same name in that dictionary, you need to come up with some other method of associating a loaded material with an existing material.
Related:
How to know which object is using a material
How can I replace a material from Python?
How to Link/Append a data-block using the Python API?