The box has no Ruby/Python/Perl etc.
Only bash, sed, and awk.
A way is to replace chars by map, but it becomes tedious.
Perhaps some built-in functionality i'm not aware of?
The box has no Ruby/Python/Perl etc.
Only bash, sed, and awk.
A way is to replace chars by map, but it becomes tedious.
Perhaps some built-in functionality i'm not aware of?
 
    
     
    
    Escaping HTML really just involves replacing three characters: <, >, and &. For extra points, you can also replace " and '. So, it's not a long sed script:
sed 's/&/\&/g; s/</\</g; s/>/\>/g; s/"/\"/g; s/'"'"'/\'/g'
 
    
    You can use recode utility:
    echo 'He said: "Not sure that - 2<1"' | recode ascii..html
Output:
    He said: "Not sure that - 2<1"
 
    
    Pure bash, no external programs:
function htmlEscape () {
    local s
    s=${1//&/&}
    s=${s//</<}
    s=${s//>/>}
    s=${s//'"'/"}
    printf -- %s "$s"
}
Just simple string substitution.
 
    
     
    
    or use xmlstar Escape/Unescape special XML characters:
$ echo '<abc&def>'| xml esc
<abc&def>
 
    
    This is an updated answer to miken32 "Pure bash, "no external programs":
bash 5.2 breaks backward compatibility in ways that are highly inconvenient.
From NEWS:
x. New shell option: patsub_replacement. When enabled, a '&' in the replacement string of the pattern substitution expansion is replaced by the portion of the string that matched the pattern. Backslash will escape the '&' and insert a literal '&'.
The option is enabled by default. If you want to restore the previous behavior, add shopt -u patsub_replacement.
So there is three ways to use miken32 code in bash 5.2+:
Either disable patsub_replacement:
shopt -u patsub_replacement
function htmlEscape () {
    local s
    s=${1//&/&}
    s=${s//</<}
    s=${s//>/>}
    s=${s//'"'/"}
    printf -- %s "$s"
}
, another option is to escape '&' with backslash in the replacement if you want to make it work regardless of the 5.2 feature, patsub_replacement:
function htmlEscape () {
    local s
    s=${1//&/\&}
    s=${s//</\<}
    s=${s//>/\>}
    s=${s//'"'/\"}
    printf -- %s "$s"
}
and another option is to quote string in the replacement:
function htmlEscape () {
    local s
    s=${1//&/"&"}
    s=${s//</"<"}
    s=${s//>/">"}
    s=${s//'"'/"""}
    printf -- %s "$s"
}
 
    
    There's much better answers, but I just found this so I thought I'd share.
PN=`basename "$0"`          # Program name
VER=`echo '$Revision: 1.1 $' | cut -d' ' -f2`
Usage () {
    echo >&2 "$PN - encode HTML unsave characters, $VER
usage: $PN [file ...]"
    exit 1
}
set -- `getopt h "$@"`
while [ $# -gt 0 ]
do
    case "$1" in
    --) shift; break;;
    -h) Usage;;
    -*) Usage;;
    *)  break;;         # First file name
    esac
    shift
done
sed                                     \
    -e 's/&/\&/g'                       \
    -e 's/"/\"/g'                      \
    -e 's/</\</g'                        \
    -e 's/>/\>/g'                        \
    -e 's/„/\ä/g'                      \
    -e 's/Ž/\Ä/g'                      \
    -e 's/”/\ö/g'                      \
    -e 's/™/\Ö/g'                      \
    -e 's//\ü/g'                       \
    -e 's/š/\Ü/g'                      \
    -e 's/á/\ß/g'                     \
    "$@"
 
    
    The previous sed replacement defaces valid output like
<
into
&lt;
Adding a negative loook-ahead so "&" is only changed into "&" if that "&" isn't already followed by "amp;" fixes that:
sed 's/&(?!amp;)/\&/g; s/</\</g; s/>/\>/g; s/"/\"/g; s/'"'"'/\'/g'
 
    
    