#!/usr/bin/env bash set -eo pipefail image="$1"; [ -z "$1" ] && { echo "No image file specified!" >&2; exit 1; } mfile="$2"; [ -z "$2" ] && { echo "No mapfile specified!" >&2; exit 1; } [ -z "$3" -a -t 1 ] && { echo "The output of this script is unsafe for raw display." >&2 exit 1; } \ || ofile=${3:-/dev/stdout} BLOCKSIZE=`sed -nE 's/^#BLOCKSIZE=([0-9]+)$/\1/p' "$mfile"` [ -z "$BLOCKSIZE" ] && { echo "Mapfile does not specify blocksize!" >&2; exit 1; } shopt -s expand_aliases alias dd="dd bs=$BLOCKSIZE status=none" { i=0 while read -r -d$'\n' _ block lengt _; do #Leaves the remainder block for convenience dd if="$image" skip=$i count=$((block-i)) dd if=/dev/zero count=$((lengt-1)) i=$((block+lengt-1)) done < <(grep -v ^\# "$mfile" | sed -En '/[a-f0-9]{64}/!p' | sort -unk2) dd if="$image" skip=$i } > "$ofile"