如何在bash中遍历字母表中的前n个字母

时间:2015-03-26 19:43:07

标签: bash loops

我知道要循环使用字母表,可以做到

for c in {a..z};  do   something;  done

我的问题是,我如何遍历第一个n字母(例如构建字符串),其中n是命令行中给出的变量/参数。

我搜索了SO,并且只找到了对数字执行此操作的答案,例如使用C风格的for循环或seq(参见例如How do I iterate over a range of numbers defined by variables in Bash?)。我的环境中没有seq

感谢。

5 个答案:

答案 0 :(得分:7)

直截了当的方法是将它们粘贴在一个数组中并通过索引循环遍历:

#!/bin/bash
chars=( {a..z} )
n=3
for ((i=0; i<n; i++))
do
  echo "${chars[i]}"
done

或者,如果你只想让它们分开:

printf "%s-" "${chars[@]:0:n}"

答案 1 :(得分:3)

that other guy's answer可能是要走的路,但这是一个替代方案,不需要数组变量

n=3 # sample value

i=0 # var. for counting iterations
for c in {a..z};  do 
  echo $c # do something with "$c"
  (( ++i == n )) && break # exit loop, once desired count has been reached
done

@rici在评论中指出你可以在没有辅助的情况下做到。变量$i使用条件(( n-- )) || break退出循环,但请注意,这会修改$n


这是另一个使用子字符串提取(参数扩展)的无数组但效率较低的方法:

n=3 # sample value

# Create a space-separated list of letters a-z.
# Note that chars={a..z} does NOT work.
chars=$(echo {a..z})

# Extract the substring containing the specified number
# of letters using parameter expansion with an arithmetic expression,
# and loop over them.
# Note:
#  - The variable reference must be _unquoted_ for this to work.
#  - Since the list is space-separated, each entry spans 2 
#    chars., hence `2*n` (you could subtract 1 after, but it'll work either way).
for c in ${chars:0:2*n};  do 
  echo $c # do something with "$c"
done

最后,你可以结合数组和列表方法来实现简洁,尽管纯数组方法更有效:

n=3 # sample value

chars=( {a..z} ) # create array of letters

# `${chars[@]:0:n}` returns the first n array elements as a space-separated list
# Again, the variable reference must be _unquoted_.
for c in ${chars[@]:0:n}; do
  echo $c # do something with "$c"
done

答案 2 :(得分:1)

您是否只是在字母表上进行迭代以创建子集?如果是这种情况,那就简单一点:

 $ alpha=abcdefghijklmnopqrstuvqxyz
 $ n=4
 $ echo ${alpha:0:$n}
 abcd

修改即可。根据您的评论,您有sed吗?

% sed -e 's/./&-/g' <<< ${alpha:0:$n}
a-b-c-d-

答案 3 :(得分:1)

您可以遍历字母表中字母的字符代码并来回转换:

# suppose $INPUT is your input
INPUT='x'
# get the character code and increment it by one
INPUT_CHARCODE=`printf %x "'$INPUT"`
let INPUT_CHARCODE++

# start from character code 61 = 'a'
I=61  
while [ $I -ne $INPUT_CHARCODE ]; do
    # convert the index to a letter
    CURRENT_CHAR=`printf "\x$I"`
    echo "current character is: $CURRENT_CHAR"
    let I++
done

答案 4 :(得分:0)

这个问题和答案部分地帮助了我解决问题。
我需要以bash中的字母 为基础,放大字母的一部分。

尽管扩展is strictly textual

I found a solution:并使其变得更加简单:

START=A
STOP=D
for letter in $(eval echo {$START..$STOP}); do
    echo $letter
done

这将导致:

A
B
C
D

希望这对寻找我必须解决的相同问题的人很有帮助, 并在这里结束

also answered here

原始问题的完整答案是:

START=A
n=4

OFFSET=$( expr $(printf "%x" \'$START) + $n)
STOP=$(printf "\x$OFFSET") 

for letter in $(eval echo {$START..$STOP}); do
    echo $letter
done

结果相同:

A
B
C
D