#bash #shell #grep
#bash #оболочка #grep
Вопрос:
Я пытаюсь сопоставить все символы заданной строки, но эти символы должны совпадать в порядке, указанном в скрипте bash.
while [[ $# -gt 0 ]]; do
case $1 in
-i)
arg=$2
egrep "*[$arg]*" words.txt
shift ;;
esac
shift
done
$ sh match_the_pattern.sh -i aei words.txt
Должны возвращать такие слова, как
abstentious
adventitious
sacrilegiousness
Если вы заметили, что сначала a
сопоставляется тогда e
, а затем i
, все они в порядке. Кроме того, все слово сопоставляется и фильтруется.
Ответ №1:
Вы можете использовать getopts
с некоторой заменой параметров bash для построения строки запроса.
#!/bin/bash
while getopts 'i:' choice
do
case "${choice}" in
i)
length=${#OPTARG}
for((count=0;count<length;count ))
do
if [ $count -eq 0 ]
then
pattern="${pattern}.*${OPTARG:count:1}.*"
else
pattern="${pattern}${OPTARG:count:1}.*"
fi
done
;;
esac
done
# The remaining parameter should be our filename
shift $(($OPTIND - 1))
filename="$1"
# Some error checking based on the parsed values
# Ideally user input should not be trusted, so a security check should
# also be done,omitting that for brevity.
if [ -z "$pattern" ] || [ -z "$filename" ]
then
echo "-i is must. Also, filename cannot be empty"
echo "Run the script like ./scriptname -i 'value' -- filename"
else
grep -i "${pattern}" "$filename"
fi
Обратитесь к этому, чтобы узнать больше о parameter substitution
и для этого getopts
.
Ответ №2:
Измените это:
arg=$2
egrep "*[$arg]*" words.txt
для этого:
arg=$(sed 's/./.*[amp;]/g' <<< "$2")
grep "$arg" words.txt
Если это не все, что вам нужно, отредактируйте свой вопрос, чтобы уточнить ваши требования и предоставить более репрезентативный образец ввода / вывода.
Комментарии:
1. Вероятно, вы могли бы сделать
grep "$arg" "$3"
, если команда естьsh script.sh -i aei words.txt
.2. Да, есть несколько других «возможностей» для улучшения сценария OPs :-).
3. Ваше решение довольно хорошее, хотя статическое «words.txt » в grep кажется излишним, поскольку, похоже, он уже включает его в качестве аргумента в свою команду, это действительно все, на что я указывал. Приветствия!
4. Я полностью понимаю, но я просто показываю оператору, как делать то, о чем она конкретно просила, и минимизировать изменения в ее сценарии, чтобы то, что ей нужно сделать для этой конкретной проблемы, было как можно более ясным, а не запутывать его другими несвязанными изменениями. Смысл моего комментария заключается только в том, что в ее скрипте есть несколько других вещей, которые также можно улучшить, включая жестко заданное имя файла.
5. Да, понятно; Я действительно не из тех людей, которые ожидают, что кто-то, отвечающий на вопрос, перепишет весь сценарий persons, в любом случае это хорошее простое решение (поддержано ранее).
Ответ №3:
Ваше регулярное выражение соответствует ‘a’ или ‘e’ или ‘i’, потому что они находятся в наборе символов ( []
). Я думаю, что регулярное выражение, которое вы ищете, это
a .*e .*i .*
который соответствует ‘a’ один или несколько раз, затем что угодно, затем ‘e’ один или несколько раз, затем что угодно, затем ‘i’ один или несколько раз.
Комментарии:
1. Очевидно, что op необходимо создать такой шаблон, учитывая аргумент
-i
параметра, который составляет суть проблемы.