您编辑了您的帖子并发布了一个丑陋且破碎的答案。在纯 Bash 中更简单、更有效、更有效:
#!/bin/bash
key=$1
mkey=$key
for ((i=0;i<${#mkey};++i)); do
c=${mkey:i:1}
tailmkey=${mkey:i+1}
mkey=${mkey::i+1}${tailmkey//"$c"/}
done
echo "$mkey"
为什么你的脚本坏了?以下是一些你的失败而我的失败的情况。为了演示,我调用了你的脚本banana 和我的gorilla。哦,因为我不是故意的,所以我修复了您的脚本存在的琐碎引用问题(与* 字符无关)并评论了泛滥的部分:
#!/usr/bin/bash
key=$1
len=${#key}
mkey=""
for (( c=0; c<len; c++ )); do
tmp=${key:$c:1}
echo "$mkey" | grep "$tmp" >/dev/null 2>&1 # Added quotes here!
if [ "$?" -eq "0" ]; then
: # echo "Found $tmp in $mkey" # Commented this to remove flooding
else
mkey+=$tmp
fi
done
echo "$mkey" # Added quotes here!
那么我们走吧:
$ ./banana '^'
$ ./gorilla '^'
'^'
是的,那是因为^ 是 grep 的正则表达式中使用的字符。 $ 和 . 也会发生类似的事情:
$ ./banana 'a.'
a
$ ./gorilla 'a.'
a.
现在反斜杠也会导致问题:
$ ./banana '\\'
\\
$ ./gorilla '\\'
\
(删除>/dev/null 2>&1 部分以查看grep: Trailing backslash 错误)。 [ 也会发生同样的事情。
更不用说您的脚本效率极低!它多次调用grep。在这方面我的要好一点:
$ time for i in {1..200}; do ./banana cabbage; done &>/dev/null
real 0m3.028s
user 0m0.216s
sys 0m0.464s
$ time for i in {1..200}; do ./gorilla cabbage; done &>/dev/null
real 0m0.878s
user 0m0.172s
sys 0m0.324s
还不错吧?
另一个不言自明的基准:用长字符串,例如,Lorem Ipsum 的一段:
$ time ./banana 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.'
Lorem ipsudlta,cngDSMqvhPbNAUfCI
real 0m1.464s
user 0m0.104s
sys 0m0.224s
$ time ./gorilla 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.'
Lorem ipsudlta,cng.DSMqvhPbNAUfCI
real 0m0.013s
user 0m0.000s
sys 0m0.008s
这是因为banana 为输入字符串的每个字符调用grep,而gorilla 动态执行删除。 (我不会提到banana 错过了这段时间)。