Skip to content

Instantly share code, notes, and snippets.

@kugland
Last active June 9, 2022 01:47
Show Gist options
  • Save kugland/20ea5e8ea6e978d27468ac78ded043ed to your computer and use it in GitHub Desktop.
Save kugland/20ea5e8ea6e978d27468ac78ded043ed to your computer and use it in GitHub Desktop.
Escape strings in Zsh
typeset -A escape_map
escape_map[_\\]='\\'
for code escape (
0 C@ 1 Ca 2 Cb 3 Cc 4 Cd 5 Ce 6 Cf 7 a
8 b 9 t 10 n 11 v 12 f 13 r 14 Cn 15 Co
16 Cp 17 Cq 18 Cr 19 Cs 20 Ct 21 Cu 22 Cv 23 Cw
24 Cx 25 Cy 26 Cz 27 e 28 'C\\' 29 'C]' 30 'C^' 31 C_
) {
printf -v code '\%03o' $code
printf -v code $code
escape_map[_$code]='\'$escape
}
for code ({127..255}) {
printf -v escape '\%03o' $code
printf -v code $escape
escape_map[_$code]=$escape
}
escape_str() {
local LANG=C
setopt local_options extended_glob
print -nr \$\'
for (( i=0; i < ${#1}; i++ )) {
local ch=${1:$i:1}
if [[ -n $escape_map[_$ch] ]] {
print -rn -- $escape_map[_$ch]
} elif [[ $ch = $'\'' ]] {
print -rn -- $'\\\''
} else {
print -rn -- $ch
}
}
print -rn \'
}
LANG=C
total=0
while :; do
S="$(cat /dev/urandom | head -c 1024)"
Z="$(eval print -rn -- "$(escape_str "$S")")"
if [[ $S != $Z ]]; then
>&2 ( escape_str "$S"; echo '' )
diff -Naur <(print -rn -- "$S" | od -tx1a | head -n 2) <(print -rn -- "$Z" | od -tx1a | head -n 2)
fi
total=$(( total + 1024 ))
echo $total
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment