import fnmatch


def filter_outputs(patterns, sys):
    """
    Find all outputs of the given system that match one or more of the strings given in patterns.

    Parameters
    ----------
    patterns : str or Sequence
        A string or sequence of strings to be matched in the outputs of the given system.  These
        may include glob patterns.
    sys : System
        The OpenMDAO system whose outputs are to be filtered.

    Returns
    -------
    dict of {str: dict}
        A dictionary where the matching output names are the keys and the associated dict provides
        the 'units' and 'shapes' metadata.
    """
    outputs = {opts['prom_name']: opts for (k, opts) in
               sys.get_io_metadata(iotypes=('output',), metadata_keys=['shape', 'units']).items()}
    output_names = list(outputs.keys())
    filtered = []
    results = {}

    for pattern in patterns:
        filtered.extend(fnmatch.filter(output_names, pattern))
    filtered = list(set(filtered))  # de-dupe

    for var in filtered:
        results[var] = {'units': outputs[var]['units'], 'shape': outputs[var]['shape']}

    return results