我有一个练习,我必须从用户那里获取一个字符串read str
并打印该字符串的最后一个字符被重复的次数。
例如,字符串是:ab2aa2b122
,输出将是:4
因为2
在字符串中重复了 4 次。
我的问题是将字符串分成单个字符。" "
我希望每个字符都用空格或 a与另一个字符分开,\n
以便使用tr
命令和uniq
命令。
我必须使用uniq
andsort
命令,为了使用这些我必须拆分字符,这意味着每个字符必须用空格或\n
.
100% 纯 bash 解决方案:
read -r -p "Enter your string: " a
l=${a:(-1)}
b=${a//[^$l]/}
n=${#b}
echo "Last character is \`$l' and is repeated $n times in the string \`$a'"
没有循环,没有外部进程,什么都没有!
作为单线(以表明它真的很短,并且可能是最短的!):
echo "ab2aa2b122"|{ read -r a;b=${a//[^${a: -1}]/};echo ${#b};}
第一个版本的解释(第二个完全一样,但适合代码高尔夫比赛)。
a
。l=${a:(-1)}
将存储 in 的最后一个a
字符l
。更一般地,${a:i:j}
扩展为a
从索引i开始、长度为j的子字符串。当i =-1 时,它扩展到最后一个字符。${a//P/R}
将扩展为a
所有的P
' 替换为R
。在这里,R
是空的,并且P
是[^$l]
,所以这匹配所有不同于 的字符l
。底线:${a//[^$l]/}
扩展到a
删除与最后一个不同的所有字符的位置。所以我们只剩2222
下你的情况了。${#b}
扩展到b
(这里是它的长度)的大小。所以我们完成了!不确定您是否可以sed
在锻炼中使用,但sed
可以这样做:
bash-3.1$ PPP=`echo ab2aa2b122 | sed 's/\(.\)/\1 /g'`
bash-3.1$ echo $PPP
a b 2 a a 2 b 1 2 2
awk 单线:
kent$ echo "ab2aa2b122"|awk 'BEGIN{FS=""}{for(i=1;i<=NF;i++)a[$i]++;print "last char "$NF" : "a[$NF]" times";}'
last char 2 : 4 times
如果您只想获得数字“4”:
kent$ echo "ab2aa2b122"|awk 'BEGIN{FS=""}{for(i=1;i<=NF;i++)a[$i]++;print a[$NF]}'
4
仅使用wc
,cut
和tr
:
#/bin/bash
input="ab2aa2b122"
length=$(wc -c <<< $input)
last=$(cut -c $((length-1)) <<< $input)
tr -dc $last <<< $input | wc -c
wc -c
计算字符串中的字符数。
cut -c $len-1
获取字符串中的最后一个字符
tr -dc $last
删除所有不是最后一个字符(即 2 个)离开字符串2222
,然后用于wc -c
再次计算长度。
./script.sh
4
从OP:
我的问题是将字符串分成单个字符。我希望每个字符都将通过空格(“”)或 \n(下一行)与另一个字符分隔 - 以便使用 tr 命令和 uniq 命令。
从作为评论留下的评论到我的其他答案:
我学习了基本命令,例如 cat、cut、tr、sort、uniq、for 和 while 循环、if、cp、wc、输入输出 (>|)、abit of globe 样式和扩展正则表达式 (egrep..)但我可以在当前练习中使用 egrep 和 Extended reg 表达式,以及地球样式。谢谢!
使用“划分”你的字符串grep
:
使用可怕的echo
-pipe 和 subshell:
echo "$string" | grep -o '.'
使用此处的字符串:
grep -o '.' <<< "$string"
希望这可以帮助!