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'