Как печатать строки, содержащие только символы из списка в BASH?

у меня есть файл под названием "словарь.txt", содержащий список всех возможных слов, например:

a
aardvark
act
anvil
ate
...

как я могу искать это, только печатая строки, содержащие буквы из ограниченного списка, например, если список содержит буквы "c", "a" и "t", поиск покажет эти слова:

a
act
cat

Если искать буквы "e", "a" и "t", то из "словаря" можно найти только эти слова.txt":

a
ate
eat
tea

единственное решение, которое мне удалось это:

  • создать список всех возможных букв.
  • удалите искомые буквы из этого списка, оставив список букв, которые я не хочу искать.
  • С циклическим циклом for для каждой из этих букв удалите все строки из словаря, содержащего эти буквы.
  • печать оставшихся слов, найденных в словаре.

это решение очень медленно. Кроме того, мне нужно использовать этот код с другими языки, которые имеют тысячи возможных символов, поэтому этот метод поиска особенно медленный.

как я могу печатать только эти строки из " dictionary.txt", которые содержат только искомые буквы, и ничего больше?

5 ответов


grep '^[eat]*$' dictionary.txt

пояснение:

^ = маркер означает начало строки

$ = маркер означает конец строки

[abc] = класс символов ("соответствует любому из этих символов")

* = множитель для класса символов (ноль или более повторений)


к сожалению, я не могу комментировать, иначе я бы добавил к amphetamachine это. В любом случае, с обновленным состоянием тысяч символов поиска вы можете сделать следующее:

grep -f patterns.txt dictionary.txt

здесь patterns.txt - это ваше регулярное выражение:

/^[eat]\+$/

Ниже приведен пример сеанса:

$ cat << EOF > dictionary.txt
> one
> two
> cat
> eat
> four
> tea
> five
> cheat
> EOF
$ cat << EOF > patterns.txt
> ^[eat]\+$
> EOF
$ grep -f patterns.txt dictionary.txt
eat
tea
$

таким образом, вы не ограничены оболочкой (список аргументов слишком длинный). Кроме того, вы можете указать несколько шаблонов в файле:

$ cat patterns.txt
^[eat]\+$
^five$
$ grep -f patterns.txt dictionary.txt
eat
tea
five
$

попробуйте использовать awk:

awk '/^[eat]*$/ { print }' dictionary.txt

я обнаружил, что это, по крайней мере, на порядок быстрее, чем grep для более чем 7 букв. Однако я не знаю, столкнетесь ли вы с той же проблемой с тысячами писем, поскольку я не проверял столько.

вы даже можете искать несколько шаблонов одновременно (это быстрее, чем поиск каждого шаблона по одному, так как файл словаря будет прочитан только один раз). Каждая модель действует как если заявление:

awk '/^[eat]*$/ { print "[eat]: "  } /^[cat]*$/ { print "[cat]: "  }' dictionary.txt

sed -n '/a/'p words.txt

используйте это для любой буквы, которую вам нужно найти. Если вы хотите найти более одной буквы вместе, просто повторите команду.

Grep также не следует использовать для более чем самых простых / элементарных поисков, IMHO. Хотя я обычно не решаюсь назвать любую из утилит POSIX устаревшей, я стараюсь избегать grep. Его синтаксис крайне непоследователен.

изучение этого текстового файла также рекомендуется. http://sed.sourceforge.net/sed1line.txt


Если вы хотите включить, например, Umlauts в шаблон и не хотите иметь другие акценты, установите LC_ALL="C" перед выполнением grep.

это, например, даст вам только кандидаты немецких слов в потенциальном словаре.txt-файл.

LC_ALL="C" grep '^[a-zA-ZäÄöÖüÜß]*$' dictionary.txt