I’ve just had the same problem. In 22 years of industry, that’s the first time I see a program where you duplicate something and the internal dependencies aren’t properly redirected to the adequate duplicates.! I considered writing something in Unity for a while, but I ended up deciding for an easier (although not elegant) hack that will do the trick, as long as you’re using visible meta files as the version control mode.
I wrote a python script that changes the guids of the assets as well as the internal references in materials and prefabs. I’m using python 3.5 on this one, but it should work on later versions as well. Have a back-up of the project folder, for I’ve tested it enough for my own personal use only.
>> USE AT YOUR OWN RISK <<
Usage: python scriptname.py -i foldername
I pulled a copy of the folder I wanted to duplicate out of the project, renamed it and ran the script. As it doesn’t affect guid references that are not found inside the folder itself, when you move the renamed folder to the project , Unity correctly matches the external references. 
Just to make sure you’ve read it: >> USE AT YOUR OWN RISK <<
import fnmatch
import os
import argparse
import uuid
# PARAMETERS
parser = argparse.ArgumentParser(description='Rearrange a Unity\'s project folder guids.')
parser.add_argument('-i, --input', metavar='FOLDER', type=str, nargs=1, required=True, dest='input_folder',
help='input folder')
args = parser.parse_args()
input_folder = None if args.input_folder is None else args.input_folder[0]
if not os.path.isdir(input_folder):
print('ERROR: Path not found.')
quit(1)
# SCAN FILES
register_list = []
print('')
metas = dict()
mats = []
prefabs = []
for root, folders, files in os.walk(input_folder):
for fname in files:
if fnmatch.fnmatch(fname, '*.meta'):
metaname = root + os.sep + fname
file = open(metaname, 'r')
for line in file:
elements = line.split(': ')
if elements[0] == 'guid':
id = elements[1].replace('
', ‘’)
metas.update({id: [metaname, uuid.uuid4().hex]})
file.close()
if fnmatch.fnmatch(fname, ‘.mat’):
mats += [root + os.sep + fname]
if fnmatch.fnmatch(fname, '.prefab’):
prefabs += [root + os.sep + fname]
# CHANGE METAS
for k, v in metas.items():
file = open(v[0], 'r')
met = file.readlines()
for i, l in enumerate(met):
if 'guid:' in l:
met *= l.replace(k, v[1])*
file.close()
file = open(v[0], ‘w’)
file.writelines(met)
file.close()
#CHANGE PREFABS AND MATERIALS
for pname in prefabs + mats:
file = open(pname, ‘r’)
changed = False
prefab = file.readlines()
for i, l in enumerate(prefab):
if ‘guid:’ in l:
key = None
for k in metas.keys():
if k in l:
key = k
changed = True
if key is not None:
prefab = l.replace(key, metas[key][1])
print(prefab*, end=‘’)*
print(key, ‘->’, metas[key][1])
else:
print(prefab*)*
file.close()
if changed:
file = open(pname, ‘w’)
file.writelines(prefab)
file.close()