Вы отредактировали свой пост и опубликовали ответ, который уродлив и сломан. Более простой, работающий и более эффективный, в чистом 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
пропустил точку).
person
gniourf_gniourf
schedule
01.05.2014