Tuesday, November 24, 2015

Sed Inserts via Process Substitution w/out backslashes

Sometimes its useful to be able to insert text wherever you would like in a file using a function that generates a multiline output. Sed is useful for the task but not without the gotcha of backslashes, all but the last backslash will normally remain unless you work to prevent sed from leaving them in.
#!/bin/bash 

declare -r TST_FILE="/tmp/__${0##*/}__$$" 

function print_header() { 
cat << EOF
-------------------------------------------------------------------
-------------------------------------------------------------------
-------------------------------------------------------------------
$(date '+%B %d, %Y @ ~ %r')  ID:$RANDOM
EOF
} 

function gen_test_file() { 
cat << EOF
line 1
line 2
line 3
line 4
line 5
EOF
}

gen_test_file > "${TST_FILE}"

[[ -z ${1} ]] && read -p "Enter line # to insert the multiline header (0-5):" -u 0 response || response=${1}  
[[ ! -z ${response} ]] && grep -q -o '^[0-9]*$' <<< "${response}" && ((${response} > -1)) && ((${response} < 6)) && : || 
{ echo "*** Out of range line ($response) using line zero.." && response=0; }
  ## If its before the first line (line 0) we need to use insert i because we can't replace address 0 in sed. 
((${response}==0)) && sed "1 i $(print_header | sed 's/$/\\/g;$s/$/\x01/')" "${TST_FILE}" | tr -d '\001' ||
  ## Otherwise we can use a slightly easier on the eyes replacement r.  
echo -en "$(print_header)\n" | sed ${response:-1}r/dev/stdin "${TST_FILE}"
rm -f "${TST_FILE}"
exit 0 
Thanks to Triplee for the sed r/dev/stdin idea.

No comments:

Post a Comment