Команда grep
распечатает строку, когда строка содержит строку, которая соответствует выражению, которое не удобно для поиска specifed содержания.
Например, у меня есть файлы словаря с форматированием
**word**
1. Definition:
2. Usage
3. Others
Я хотел бы получить все слова для создания списка слов в файлах
grep '\*\*[^*]*\*\*'
Возвращает объем содержания.
Как использовать grep
поймать только word
?
С awk
путь:
awk -F'*\\*' 'NF>2{print $2}' infile
демонстрационный тест ввел:
*wrd*
*woooord
**WRD
WORD**
woooooooooood*
**word**
вывод:
word
Как это для слова, с помощью жемчуга regex (-P
) :
grep -oP '^\s*\*\*\K[^*]+(?=\*\*)' file
word
Как это для слов:
grep -oP '^\s*\d+\.\s*\K\w+' file
Definition
Usage
Others
Существует несколько инструментов, доступных, который может использоваться для извлечения слова, вот версия, реализованная в sed:
sed '/^\*\*/!d' <your_file
Эта команда будет соответствовать каждой строке в Вашем файле, который запускается с **
и распечатайте его. Другие строки будут удалены из вывода. Если Вы также хотите удалить звезды, можно расширить команду до этого:
sed '/^\*\*/!d;s/\*//g' <your_file
Эта команда, кроме того, удалит все *
символы от строки, прежде чем это будет распечатано.
Это - один из тех вопросов, где полезно иметь тестовый входной файл и примеры желаемого вывода.
Вот тестовый входной файл, который я скопировал с Интернета и изменил для монтирования в корпус поисковых слов в **
пары:
$ cat ~/Downloads/wordlist.txt
**Schadenfreude**
This is a German word, although used in English too, which is used to mean ‘malicious enjoyment of the misfortunes of others’. It comes from the joining of the words schaden meaning ‘harm’ and freude meaning ‘joy’.
**Waldeinsamkeit**
Ever found yourself wandering alone through a forest and wanting to express the emotion brought about by that wander? Look no further! In German, Waldeinsamkeit means ‘woodland solitude’.
**L’esprit de l’escalier**
We all know the feeling of walking away from an argument and instantly thinking of the ideal comeback, or leaving a conversation and remembering the perfect contribution to a no-longer relevant subject. In French, l’esprit de l’escalier is the term used to refer to that irritating feeling. It literally translates as ‘the spirit of the staircase’, more commonly known as ‘staircase wit’. It comes from the idea of thinking of a response as you’re leaving somebody’s house, via their staircase.
**Schlimazel**
The Mr Men series of books by Roger Hargreaves is a staple of many a British child’s bookshelves, and there is a word which could have been created for the character Mr Bump. Like Mr Bump, a Schlimazel is ‘a consistently unlucky, accident-prone person, a born loser’. It is a Yiddish word, coming from the Middle High German word slim meaning ‘crooked’ and the Hebrew mazzāl meaning ‘luck’.
**Depaysement**
Ever go on holiday, only to experience a strange sensation of disorientation at the change of scenery? Dépaysement is a French word which refers to that feeling of disorientation that specifically arises when you are not in your home country.
**Duende**
This Spanish term implies something magical or enchanting. It originally referred to a supernatural being or spirit similar to an imp or pixie (and is occasionally borrowed in that sense into English with reference to Spanish and Latin American folklore). Now, it has adapted to refer to the spirit of art or the power that a song or piece of art has to deeply move a person.
**Torschlusspanik**
Are you getting older? Scared of being left behind or ‘left on the shelf’? This British idiom has its own word in German: Torschlusspanik, which literally translates as ‘panic at the shutting of a gate’, is used frequently in a general sense meaning ‘last –minute panic’, of the type you might experience before a deadline.
*Do*Not*Return*these four star lines
*word***
***word*
word**
grep
Используя grep
это довольно просто для получения списка слов:
$ grep -E -o '\*\*[^*]{,20}\*\*' ~/Downloads/wordlist.txt
**Schadenfreude**
**Waldeinsamkeit**
**L’esprit de l’escalier**
**Schlimazel**
**Depaysement**
**Duende**
**Torschlusspanik**
Если Вы хотите удалить **
при монтировании в корпус слов добавьте канал к sed
:
$ grep -E -o '\*\*[^*]{,20}\*\*' ~/Downloads/wordlist.txt | sed 's/*//g'
Schadenfreude
Waldeinsamkeit
L’esprit de l’escalier
Schlimazel
Depaysement
Duende
Torschlusspanik
Если Вы хотите сохранить Ваш grep
и sed
выходное использование перенаправление файла >
команда:
$ grep -E -o '\*\*[^*]{,20}\*\*' ~/Downloads/wordlist.txt | sed 's/*//g' > ~/Downloads/wordlist-index.txt
$ cat ~/Downloads/wordlist-index.txt
Schadenfreude
Waldeinsamkeit
L’esprit de l’escalier
Schlimazel
Depaysement
Duende
Torschlusspanik
Отметьте исходный ответ, отправленный вчера улучшенный с новым сообщением сегодня от muru на отдельные Вопросы и ответы: Используйте указанный квантор в grep для получения удовлетворенного словаря
Если бы Вы не возражаете использовать дополнительные инструменты, очень простое решение состояло бы в том, чтобы постотфильтровать grep
вывод с tr
удалить все случаи символа *
:
grep -x '\*\*[^*]*\*\*' | tr -d '*'
Я также рекомендую использовать -x
флаг GNU grep как выше для соответствия только целым строкам к не случайно ловит **word**
попытка казаться окруженным другим текстом на той же строке. Это может также ускорить процесс сопоставления с образцом, так как он может теперь отбросить много потенциальных соответствий вначале.
sed
альтернативаМожно также использовать в своих интересах sed’s p
отметьте, чтобы соответствовать, заменить и распечатать как единственная команда:
sed -nre 's/^\*\*([^*]*)\*\*$/\1/p'
Ваш особый случай извлекает текст между двумя шаблонами на строке/строке. Это было покрыто вопросом 2012 года, Как использовать sed/grep для извлечения текста между двумя словами?. Особенно, как anishsane упомянутый, можно использовать предвидение и шаблоны взгляда назад с флагом Perl-regex -P
. В Вашем особом случае решение было бы
grep -o -P '(?<=\*\*).*(?=\*\*)' input.txt
Однако как ghoti упомянутый, -P
характерно для GNU grep
. Имейте это в виду при портировании сценариев/команд между различным *, отклоняют системы.
Вместо того, чтобы пытаться использовать Perl regex, позвольте нам просто использовать сам Perl:
$ perl -a -F\\*\\* -lane 'print $F[1] if /\*\*/' input.txt
word
Это имеет два преимущества. Один, это указывает разделитель для "полей", что означает, что мы можем иметь дело с отдельными объектами, разделенными **
. Во-вторых, синтаксически это просто немного менее сбивает с толку, чем предусматривают/поддерживают шаблон.
Конечно, существуют другие способы сделать это, и одним из них является Python. Сценарий Python 2.7 был бы:
#!/usr/bin/env python
from __future__ import print_function
import sys
for f in sys.argv[1:]:
with open(f) as fd:
for line in fd:
if line.startswith('**'):
print(line.split('*')[2])
Вы могли также сделать это остротой и использовать в своих интересах stdin перенаправление:
python -c 'import re,sys; print "\n".join([ l.split("**")[1] for l in sys.stdin if "**" in l ])' < input.txt
Другие, которые предпочитают regex, могут хотеть использовать re
модуль.
python -c 'import re,sys; print "\n".join([ re.split("\*\*",l)[1] for l in sys.stdin if "**" in l ])' < input.txt