Here, James... try this: /* ========================================================= Name : MacroCleanup GitHub : Roll20 Contact : timmaugh Version : 1.0.0 Last Update : 3/1/2023 ========================================================= */ on('ready', () => { on('chat:message', msg => { // expected command line: !macrocleanup [--starts=''[ --ends=''[ --contains='']]] if (msg.type !== 'api' || !/^!macrocleanup\b/i.test(msg.content)) return; let args = msg.content.split(/\s+--/).slice(1).map(a => a.split(/=/)); if (!args.length) { sendChat('Moderator', `&{template:default}{{name=Invalid Syntax}}{{ =MacroCleanup requires at least one of **starts**, **ends**, or **contains** as an argument.}}{{Example=!macrocleanup --starts=Token --contains=Maze}}`); return; } let macros = args.reduce((m, a) => { m = m.filter(o => { switch (a[0].toLowerCase()) { case 'starts': return o.get('name').startsWith(a[1]); case 'ends': return o.get('name').endsWith(a[1]); case 'contains': return o.get('name').includes(a[1]); default: return true; } }); return m; }, findObjs({ type: 'macro' })); let allIds = `{{ **REMOVE ALL**=[Delete All](!
!macrodelete ${macros.map(m => m.id).join(' ')})}}`; if (macros.length) { macros = macros.map(m => `{{ ${m.get('name')}=[Delete](!
!macrodelete ${m.id})}}`); } else { macros.push(`{{ =No scripts found that match that criteria.}}`) } sendChat('Moderator', `&{template:default}{{name=Matching Macros}}${macros.join('')}${allIds}`); }); on('chat:message', msg => { if (msg.type !== 'api' || !/^!macrodelete\b/i.test(msg.content)) return; msg.content.split(/\s+/).slice(1).forEach(a => { let m = findObjs({ type: 'macro', id: a })[0]; if (m) { log(`Deleting... ${m.get('name')}`); log(m.get('action')); m.remove(); } }) }); }); B asic usage is to run: !macrocleanup ...and include at least one argument in the form of: --starts=starting text --ends=ending text --contains=text All arguments will serve as filters, so you can look for macros that start with a combination of characters and also include some other group of characters, etc. The script will return a list of the macros with the ability to delete them individually or to click a button that will delete them all.