#!/bin/bash usage() { echo "Usage: $0 [OPTIONS] ... [--stdin] ... " echo "This script populates a template file with content from other files and optionally standard input." echo "" echo "The position of the '--stdin' flag determines which placeholder will be filled" echo "by standard input. The placeholders are numbered sequentially starting from 1." echo "" echo "Arguments:" echo " , ... Input files whose content will be used to replace placeholders." echo " Placeholders are named %s (in the order they are provided)." echo " --stdin An optional flag. If present, the content from standard input" echo " will be used to replace the placeholder at its position." echo " The template file containing the placeholders to be replaced." echo "" echo "Options:" echo " -h, --help Show this help message and exit." echo "" echo "Example with stdin as the second placeholder:" echo " echo \"body content\" | ./template.sh nav.html --stdin foot.html template.html" echo " (Here, the first %s will be nav.html, the second %s will be stdin, and the third %s will be foot.html)" echo "" echo "Example without stdin:" echo " ./template.sh nav.html foot.html template.html" echo " (Here, the first %s will be nav.html and the second %s will be foot.html)" exit 0 } if [[ "$1" == "-h" || "$1" == "--help" ]]; then usage fi if [ "$#" -lt 2 ]; then echo "Error: Not enough arguments provided." usage fi # Initialize a variable to track the index stdin_index=0 index=0 # Iterate through the positional parameters for arg in "$@"; do index=$((index + 1)) # Check if the current argument is "--stdin" if [[ "$arg" == "--stdin" ]]; then stdin_index=$index break fi done has_stdin=false if [ "$stdin_index" -ne 0 ]; then has_stdin=true template_file="${!#}" # Split arguments into files before and after the --stdin flag files_before_stdin=("${@:1:$((stdin_index - 1))}") files_after_stdin=("${@:$((stdin_index + 1)):$(($# - stdin_index - 1))}") # Read from stdin stdin_content=$(cat) else # Without --stdin, all arguments except the last are input files template_file="${!#}" input_files=("${@:1:$(($# - 1))}") fi if [ ! -f "$template_file" ]; then echo "Error: Template file '$template_file' not found." exit 1 fi printf_args=() for file in "${files_before_stdin[@]}"; do if [ -f "$file" ]; then printf_args+=("$(cat "$file")") else echo "Warning: File '$file' not found." printf_args+=("") # Add an empty string to maintain placeholder count fi done if [ "$has_stdin" = true ]; then printf_args+=("$stdin_content") fi for file in "${files_after_stdin[@]}"; do if [ -f "$file" ]; then printf_args+=("$(cat "$file")") else echo "Warning: File '$file' not found." printf_args+=("") # Add an empty string to maintain placeholder count fi done template_content=$(<"$template_file") format_string=$(echo "$template_content" | sed -r 's/\$V[0-9]+/%s/g') printf -- "$format_string" "${printf_args[@]}"