【问题标题】:Bash-Script (separating string) [closed]Bash-Script(分隔字符串)[关闭]
【发布时间】:2012-12-22 10:38:09
【问题描述】:

我有一个练习,我必须从用户read str 那里获取一个字符串,并打印该字符串的最后一个字符重复的次数。

例如,字符串为:ab2aa2b122 并且输出将是:4,因为2 在字符串中重复了 4 次。

我的问题是将字符串分成单个字符。我希望每个字符都用空格" "\n 与其他字符隔开,以便使用tr 命令和uniq 命令。

我必须使用uniqsort 命令,为了使用这些我必须拆分字符,这意味着每个字符必须用空格或\n 分隔。

【问题讨论】:

  • 使用 GNU sed:sed 's/\B/ /g' <<<"$string"sed 's/\B/\n/g' <<<"$string" 可能是一个开始。

标签: linux bash sorting uniq


【解决方案1】:

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)} 将在l 中存储a 的最后一个字符。更一般地,${a:i:j} 扩展为 a 的子字符串,从索引 i 开始,长度为 j。当 i=-1 时,它会扩展到最后一个字符。
  • 在下一行使用参数扩展:${a//P/R} 将扩展为a,所有PR 替换。这里,R 是空的,P[^$l],所以它匹配所有不同于 l 的字符。底线:${a//[^$l]/} 扩展为 a,其中与最后一个不同的所有字符都被删除。因此,在您的情况下,我们只剩下 2222
  • ${#b} 扩展到 b 的大小(这里是它的长度)。这样我们就完成了!

【讨论】:

  • 哇,谢谢,你能告诉我第一个解决方案在做什么吗?这是一个扩展的正则表达式解决方案,对吧?如果您能解释一下,我将不胜感激。谢谢!
  • @user1923376 添加了一些解释。希望对你有帮助。
  • 非常感谢!如果我有任何问题,我可以问你吗?谢谢!
  • +1 替换的东西,真聪明
  • 对不起,我还有一个问题..我可能不会真正使用这种方式,因为,我们仍然没有学习它(我刚刚检查过),所以,我实际上必须拆分所有正如我在描述中所说的字符。这意味着每个字符都必须分开。你能给我一个解决方案吗? (您可能只是告诉如何将它们分开)-我实际上必须使用 sort 和 uniq 命令。再次道歉,非常感谢您的帮助!
【解决方案2】:

不确定您是否可以在练习中使用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

【讨论】:

  • 我学习了基本命令,例如 cat、cut、tr、sort、uniq、for 和 while 循环、if、cp、wc、输入输出 (>|)、abit of globe 样式和扩展的正则表达式(egrep..),但我可以使用 egrep 和扩展的 reg 表达式,以及这里的地球样式,所以没有 sed..
【解决方案3】:

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

【讨论】:

  • 伙计们,感谢你们所有的cmets,但我不能使用所有这些方法(因为我还没有学会它)。为了使用这些命令,我​​必须使用 uniq 和 sort 命令——我必须拆分字符,这意味着每个字符必须用空格或 \n 分隔。谢谢!
【解决方案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 和 subshel​​l:

    echo "$string" | grep -o '.'
    
  • 使用此处的字符串:

    grep -o '.' <<< "$string"
    

希望这会有所帮助!

【讨论】:

  • 我也不允许使用 grep...XD
  • 我也可以使用 grep。 :( 我真的很抱歉让我很烦.. :S 但我无法单独解决它。:(
  • @user1923376 啊但是你写了你可以使用egrep
【解决方案5】:

使用wccuttr

#/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

【讨论】:

  • 与我的答案相同的算法:-)
  • @gniourf_gniourf 希望阅读 cmets工具,但我认为这是不可能的,所以 uniqsort 不在窗口。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 2016-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多