嗨,伙计们刚刚开始用 bash 编写代码,但卡在我自己的问题中,想在字符串中计算字母重复,例如
read -p 'enter the string' str # SUPPOSE STRING USER ENTER IS
输入 =AAASSSSFFRREEE
我想得到这样的输出=A3S4F2R2E3
我能做什么,我正在尝试条件,这个程序正在使我成为猴子
-
grep -o, --only-matching
仅打印匹配行的匹配(非空)部分, 每个这样的部分都在单独的输出线上。 使用
.
作为每个字符的模式
grep -o . <<<"AASS"
A
A
S
S
<小时 />uniq -c, --count
按出现次数作为前缀行
grep -o . <<<"AASS"|uniq -c
2 A
2 S
<小时 />awk '{printf "%s%d", $2,$1}'
对输出重新排序。首先使用字符"$2",然后使用数字"$1"。 在一行中打印所有内容
grep -o . <<<"AASS"|uniq -c|awk '{printf "%s%d", $2,$1}END{print ""}'
A2S2
未排序的字母表
$ string="AAASSSSFFRREEE"
$ grep -o . <<<"$string"|uniq -c|awk '{printf "%s%d", $2,$1}END{print ""}'
A3S4F2R2E3
$ string="AAASSSSFFRREEEAAAAFFFFFEE"
A3S4F2R2E3A4F5E2
排序字母
表$ string="AAASSSSFFRREEE"
$ grep -o . <<<"$string"|sort|uniq -c|awk '{printf "%s%d", $2,$1}END{print ""}'
A3E3F2R2S4
$ string="AAASSSSFFRREEEAAAAFFFFFEE"
A7E5F7R2S4
一种解决方案可能是遍历字符串并在计数时去除第一个字符。
例:
#!/bin/bash
IFS='' read -rp 'enter the string: ' str
res=''
# loop while the string is not empty
while [[ -n $str ]]
do
# get the first character
ch=${str:0:1}
# create a regex matching the start of the string,
# on one or more of the first character
regex="^($ch+)"
# perform the regex matching
[[ "$str" =~ $regex ]]
# the matching string
match="${BASH_REMATCH[1]}"
# concatenate the character + the count to the result
res="$res$ch${#match}"
# remove the matching characters from the string
str=${str#"$match"}
done
# print the result
printf "%sn" "$res"
例子:
Input | |
---|---|
AAASSSSFFRREEE | : left;">A3S4F2R2E3 |
AAASSSSFFRREEEAAAFFFFFEE | > |
使用任何 awk:
$ cat tst.awk
{
$0 = toupper($0)
while ( char = substr($0,1,1) ) {
printf "%s%d", char, gsub(char,"")
}
print ""
}
$ echo 'AAASSSSFFRREEE' | awk -f tst.awk
A3S4F2R2E3
上面假设输入不包含任何正则表达式元字符(你说这是在字母上工作,所以这很好),如果字母不是全部连续的,你需要以下输出(你没有回答@ArnaudValmary的问题):
$ echo 'AAASSSSFFRREEEAAAFFFFFEE' | awk -f tst.awk
A6S4F7R2E5
这是一个基于awk
的解决方案,它接受任何未排序的输入,并生成排序的输出:
echo 'ZZZCGGGGAAASSSWSFXXXRRRYYYUUUUYYFRREEEAAAAJBBBQQQAAQQQBFFFBFFPPEE' |
{m,n,g}awk '{
26 for(_= ( ___=(_^=_+=_^=_<_)^--_) +
_^((____="")*(___+=_^_)); _<___; _++) {
26 __ = sprintf("%c",_) # if you`re not using nawk, then
# combine this with sub() below
26 sub("$", (__) gsub(__,""), ____)
}
1 gsub("[A-Z]0","", ____)
1 print ____
}'
A9B5C1E5F7G4J1P2Q6R5S4U4W1X3Y5Z3