diff --git a/Trigger/TrigTools/TrigByteStreamTools/bin/trigbs_updateBSMetadata.py b/Trigger/TrigTools/TrigByteStreamTools/bin/trigbs_updateBSMetadata.py
new file mode 100755
index 0000000000000000000000000000000000000000..e58236fa2cf4e026f2ee3f7f6c8fa508f5a40076
--- /dev/null
+++ b/Trigger/TrigTools/TrigByteStreamTools/bin/trigbs_updateBSMetadata.py
@@ -0,0 +1,152 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+#
+
+'''
+Write a copy of a ByteStream file with updated metadata
+'''
+
+import sys
+import argparse
+import logging
+import eformat
+import libpyevent_storage as EventStorage
+
+
+# This mapping was found in a comment in PyUtils.MetaReader
+beam_type_dict = {
+    'none': 0,
+    'protons': 1,
+    'ions': 2
+}
+
+
+def get_parser():
+    parser = argparse.ArgumentParser(usage='%(prog)s [options] FILE',
+                                     description=__doc__,
+                                     formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=36, width=100))
+    parser.add_argument('file',
+                        metavar='FILE',
+                        help='input ByteStream file')
+    parser.add_argument('--outputName', '-o',
+                        metavar='NAME', action='store',
+                        help='Output file name base. If not specified, created automatically from metadata')
+    parser.add_argument('--copyFrom', '-c',
+                        metavar='FILE', action='store',
+                        help='Copy metadata from other ByteStream file')
+    parser.add_argument('--runNumber', '-r',
+                        metavar='NUM', action='store', type=int,
+                        help='Change run number')
+    parser.add_argument('--stream', '-s',
+                        metavar='NAME', action='store',
+                        help='Change stream name')
+    parser.add_argument('--projectTag', '-p',
+                        metavar='TAG', action='store',
+                        help='Change project tag')
+    parser.add_argument('--beamType', '-b',
+                        metavar='TYPE', action='store',
+                        choices=beam_type_dict.keys(),
+                        help='Change beam type, possible values are: %(choices)s')
+    parser.add_argument('--beamEnergy', '-e',
+                        metavar='ENERGY', action='store', type=int,
+                        help='Change beam energy')
+    parser.add_argument('--lumiBlock', '-l',
+                        metavar='LB', action='store', type=int,
+                        help='Change lumi block number')
+    parser.add_argument('--triggerType', '-t',
+                        metavar='TT', action='store', type=int,
+                        help='Change trigger type')
+    parser.add_argument('--detectorMask', '-m',
+                        metavar='MASK', action='store', type=int,
+                        help='Change detector mask')
+    parser.add_argument('--verbose', '-v',
+                        action='store_true',
+                        help='Increase output verbosity')
+    return parser
+
+
+def main():
+    args = get_parser().parse_args()
+    logging.basicConfig(stream=sys.stdout,
+                        format='%(levelname)-8s %(message)s',
+                        level=logging.DEBUG if args.verbose else logging.INFO)
+
+    if args.copyFrom:
+        logging.info('Reading events from %s and metadata from %s', args.file, args.copyFrom)
+    else:
+        logging.info('Reading events and metadata from %s', args.file)
+    meta_input = args.copyFrom if args.copyFrom else args.file
+    reader = EventStorage.pickDataReader(meta_input)
+    input_stream = eformat.istream(args.file)
+
+    # Read metadata from input file
+    metadata_basic = {}  # arguments for eformat.ostream
+    metadata_extra = {}  # metadata passed as dictionary
+    metadata_basic['runNumber'] = reader.runNumber()
+    metadata_basic['triggerType'] = reader.triggerType()
+    metadata_basic['detectorMask'] = reader.detectorMask()
+    metadata_basic['beamType'] = reader.beamType()
+    metadata_basic['beamEnergy'] = reader.beamEnergy()
+    metadata_extra['Stream'] = reader.stream()
+    metadata_extra['Project'] = reader.projectTag()
+    metadata_extra['LumiBlock'] = reader.lumiblockNumber()
+
+    logging.debug('Input metadata_basic = %s', metadata_basic)
+    logging.debug('Input metadata_extra = %s', metadata_extra)
+
+    # Change metadata
+    if args.runNumber:
+        metadata_basic['runNumber'] = args.runNumber
+    if args.triggerType:
+        metadata_basic['triggerType'] = args.triggerType
+    if args.detectorMask:
+        metadata_basic['detectorMask'] = args.detectorMask
+    if args.beamType:
+        metadata_basic['beamType'] = beam_type_dict[args.beamType]
+    if args.beamEnergy:
+        metadata_basic['beamEnergy'] = args.beamEnergy
+    if args.stream:
+        metadata_extra['Stream'] = args.stream
+    if args.projectTag:
+        metadata_extra['Project'] = args.projectTag
+    if args.lumiBlock:
+        metadata_extra['LumiBlock'] = args.lumiBlock
+
+    logging.debug('Updated metadata_basic = %s', metadata_basic)
+    logging.debug('Updated metadata_extra = %s', metadata_extra)
+
+    # Create new file name
+    file_name_base = args.outputName
+    if not file_name_base:
+        # Get the name elements
+        ptag = metadata_extra['Project']
+        runno = metadata_basic['runNumber']
+        stream = metadata_extra['Stream']
+        lbn = metadata_extra['LumiBlock']
+        # Build the name
+        file_name_list = []
+        file_name_list.append(ptag if ptag else 'data')
+        file_name_list.append('{:08d}'.format(runno if runno else 0))
+        file_name_list.append(stream if stream else 'unknown_stream')
+        file_name_list.append('lb{:04d}'.format(lbn if lbn else 0))
+        file_name_base = '.'.join(file_name_list)
+
+    # Write the new file
+    metadata_extra_strings = ['{:s}={:s}'.format(k, str(v)) for k, v in metadata_extra.iteritems()]
+    output_stream = eformat.ostream(
+        core_name         = file_name_base,
+        run_number        = metadata_basic['runNumber'],
+        trigger_type      = metadata_basic['triggerType'],
+        detector_mask     = metadata_basic['detectorMask'],
+        beam_type         = metadata_basic['beamType'],
+        beam_energy       = metadata_basic['beamEnergy'],
+        meta_data_strings = metadata_extra_strings)
+
+    logging.info('Writing file %s', output_stream.current_filename().replace('.writing', '.data'))
+    for event in input_stream:
+        output_stream.write(event)
+
+
+if '__main__' in __name__:
+    sys.exit(main())