如何使用ASCII值遍历bash脚本中的一系列字符?

时间:2018-01-16 09:40:37

标签: bash shell

我正在尝试编写一个bash脚本,它将读取两个字母变量(startletter / stopletter),之后我需要使用for或其他内容从开始字母到停止字母进行打印。我怎么能这样做?

我试着做

#! /bin/bash 

echo "give start letter" 
read start 
echo "give stop letter" read stop 

但是没有一个for构造工作

#for value in {a..z} 
#for value in {$start..$stop} 
#for (( i=$start; i<=$stop; i++)) do echo "Letter: $c" done

2 个答案:

答案 0 :(得分:1)

BashFAQ/071 How do I convert an ASCII character to its decimal (or hexadecimal) value and back?

中很好地解释了这个问题
# POSIX
# chr() - converts decimal value to its ASCII character representation
# ord() - converts ASCII character to its decimal value

chr () {
  local val
  [ "$1" -lt 256 ] || return 1
  printf -v val %o "$1"; printf "\\$val "
  # That one requires bash 3.1 or above.
}

ord() {
  # POSIX
  LC_CTYPE=C printf %d "'$1"
}

根据您的要求重新使用它们,正确的脚本将被写为

read -p "Input two variables: " startLetter stopLetter
[[ -z "$startLetter" || -z "$stopLetter" ]] && { printf 'one of the inputs is empty\n' >&2 ; }

asciiStart=$(ord "$startLetter") 
asciiStop=$(ord "$stopLetter") 

for ((i=asciiStart; i<=asciiStop; i++)); do
    chr "$i"
done    

会按预期打印字母。

将其添加到社区维基,因为这也是来自Unix.SE - Bash script to get ASCII values for alphabet

的跨站点副本

答案 1 :(得分:0)

如果您喜欢冒险并希望使用zsh代替bash,则可以使用以下内容:

  • 对于5.0.7以下的zsh版本,您可以使用BRACE_CCL选项:
  

(snip man zshall)如果大括号表达式与上述形式均不匹配,则保留   除非选项BRACE_CCL(&#39;大括号字符&#39;的缩写)已设置,否则不会更改。在这种情况下,它将扩展为大括号之间的单个字符列表,这些字符按ASCII字符集中字符的顺序排序(当前未处理多字节字符)。语法类似于文件名生成中的[...]表达式:-被特别处理以表示一系列字符,但^!作为第一个字符被正常处理。例如,{abcdef0-9}   扩展为16个字0 1 2 3 4 5 6 7 8 9 a b c d e f

#!/usr/bin/env zsh

setopt brace_ccl
echo "give start letter" 
read cstart 
echo "give stop letter"
read cstop

for char in {${cstart}-${cstop}}; do echo $char; done
  • 对于5.0.7之后的zsh版本,您可以使用默认大括号扩展:
  

{c1..c2}形式的表达式,其中c1c2是单个字符(可能是多字节字符),将扩展为{{1}范围内的每个字符无论内部使用什么字符序列,都要c1。对于代码点低于128的字符,这是US ASCII(这是大多数用户需要的唯一情况)。如果任何插入字符不可打印,则使用适当的引用使其可打印。如果字符序列反转,则输出的顺序相反,例如c2被替换为{d..a}

d c b a

有关#!/usr/bin/env zsh echo "give start letter" read cstart echo "give stop letter" read cstop for char in {${cstart}..${cend}; do echo $char; done 的更多信息,请herequick reference