当我只指定要打印的字母时,为什么我的代码仍然打印出数字?

时间:2016-04-28 23:35:56

标签: bash

#!/bin/bash

# this is a sample value
hash=d7dd933b5bb968b6ba9ee40548b1b27a

# retrieve all letters from this hash
count=0
for (( i=0; i<${#hash}; i++)); do
   if [[ ${hash:i:1} == [a-f] ]] ; then
     code[$count]=${hash:i:1}    
     count=$((count + 1))
     echo ${code[i]}
     #echo ${hash:i:1}
   fi
done

不是打印哈希中的所有字符(正如我所料),而是仅打印前两个字符,然后是换行符。 (最后,我打算只从hash中提取前两个字符,但这不是一个直接的目标。)

这里有什么问题?

2 个答案:

答案 0 :(得分:0)

为了过滤掉哈希字符串中的所有字母,您可以按如下方式修改for循环:

code=()
count=0
for (( i = 0; i < ${#hash}; i++ )); do
    if [[ ${hash:i:1} == [a-zA-Z] ]]; then
        code[$count]="${hash:i:1}"
        ((count++))
    fi
done

这里,${hash:i:1}分别选择哈希中的每个字符。如果字符在字母a-zA-Z范围内,意味着它是一个字母,那么它将存储在数组code中,并累积count

考虑以下完整代码作为示例(假设它包含在名为script的文件中):

#!/bin/bash

hash="$1"                      # $1 means first argument given to this script file
printf "hash = %s\n" "$hash"

code=()                        # initialize code array
count=0
for (( i = 0; i < ${#hash}; i++ )); do
    if [[ ${hash:i:1} == [a-zA-Z] ]]; then
        code[$count]="${hash:i:1}"
        ((count++))
    fi
done

printf "All letters are: "
printf "%s" "${code[@]}"
printf "\n"

printf "First two letters are: %c%c \n" "${code[0]}" "${code[1]}"

试验:

$ ./script dd7d933b5bb968b6ba9ee40548b1b27a
hash = dd7d933b5bb968b6ba9ee40548b1b27a
All letters are: dddbbbbbaeebba
First two letters are: dd
$ ./script slfj2948347slddkshfsl2348sldfjsf
hash = slfj2948347slddkshfsl2348sldfjsf
All letters are: slfjslddkshfslsldfjsf
First two letters are: sl

答案 1 :(得分:0)

Parameter expansion提供了许多字符串操作原语,包括搜索和替换,可以很容易地用于此目的:

s=1a2b3c4d5e6f7g
code=${s//[![:alpha:]]/}
echo "$code"

......应该发出:

abcdefg

...如果你只想发出code中的前两个字符,那就是:

echo "${code:0:2}"

为什么会这样?

  • [:alpha:]是一个POSIX字符类,其中包含考虑当前语言环境中字母成员的字符。
  • [![:alpha:]]是一个glob表达式,匹配不在该类
  • 中的任何单个字符
  • ${var//value/replacement}展开名为var的变量,将value的所有实例更改为replacement
  • 因此,${s//[![:alpha:]]/}扩展变量s,将所有非字母字符的字符更改为空字符串。
相关问题