Нужна помощь в сопоставлении маттерна с использованием grep / egrep в сценариях bash

#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 параметра, который составляет суть проблемы.