Извлеките один элемент из строк текстового файла

Команда grep распечатает строку, когда строка содержит строку, которая соответствует выражению, которое не удобно для поиска specifed содержания.

Например, у меня есть файлы словаря с форматированием

**word**
1. Definition:
2. Usage
3. Others

Я хотел бы получить все слова для создания списка слов в файлах

grep '\*\*[^*]*\*\*'

Возвращает объем содержания.

Как использовать grep поймать только word?

4
задан 26 March 2018 в 09:34

6 ответов

С awk путь:

awk -F'*\\*' 'NF>2{print $2}' infile

демонстрационный тест ввел:

*wrd*
*woooord
**WRD
WORD**
woooooooooood*
**word**

вывод:

word
3
ответ дан 23 November 2019 в 11:35

Как это для слова, с помощью regex (-P) :

grep -oP '^\s*\*\*\K[^*]+(?=\*\*)' file

Вывод:

word

Как это для слов:

grep -oP '^\s*\d+\.\s*\K\w+' file

Вывод:

Definition
Usage
Others
8
ответ дан 23 November 2019 в 11:35

Существует несколько инструментов, доступных, который может использоваться для извлечения слова, вот версия, реализованная в sed:

 sed '/^\*\*/!d' <your_file

Эта команда будет соответствовать каждой строке в Вашем файле, который запускается с ** и распечатайте его. Другие строки будут удалены из вывода. Если Вы также хотите удалить звезды, можно расширить команду до этого:

sed '/^\*\*/!d;s/\*//g' <your_file

Эта команда, кроме того, удалит все * символы от строки, прежде чем это будет распечатано.

5
ответ дан 23 November 2019 в 11:35

Это - один из тех вопросов, где полезно иметь тестовый входной файл и примеры желаемого вывода.

Входной файл

Вот тестовый входной файл, который я скопировал с Интернета и изменил для монтирования в корпус поисковых слов в ** пары:

$ 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 для получения удовлетворенного словаря

3
ответ дан 23 November 2019 в 11:35

Если бы Вы не возражаете использовать дополнительные инструменты, очень простое решение состояло бы в том, чтобы постотфильтровать grep вывод с tr удалить все случаи символа *:

grep -x '\*\*[^*]*\*\*' | tr -d '*'

Я также рекомендую использовать -x флаг GNU grep как выше для соответствия только целым строкам к не случайно ловит **word** попытка казаться окруженным другим текстом на той же строке. Это может также ускорить процесс сопоставления с образцом, так как он может теперь отбросить много потенциальных соответствий вначале.

sed альтернатива

Можно также использовать в своих интересах sed’s p отметьте, чтобы соответствовать, заменить и распечатать как единственная команда:

sed -nre 's/^\*\*([^*]*)\*\*$/\1/p'
2
ответ дан 23 November 2019 в 11:35

GNU grep

Ваш особый случай извлекает текст между двумя шаблонами на строке/строке. Это было покрыто вопросом 2012 года, Как использовать sed/grep для извлечения текста между двумя словами?. Особенно, как anishsane упомянутый, можно использовать предвидение и шаблоны взгляда назад с флагом Perl-regex -P. В Вашем особом случае решение было бы

grep -o -P '(?<=\*\*).*(?=\*\*)' input.txt

Однако как ghoti упомянутый, -P характерно для GNU grep. Имейте это в виду при портировании сценариев/команд между различным *, отклоняют системы.


Perl

Вместо того, чтобы пытаться использовать Perl regex, позвольте нам просто использовать сам Perl:

$ perl -a -F\\*\\* -lane 'print $F[1] if /\*\*/' input.txt
word

Это имеет два преимущества. Один, это указывает разделитель для "полей", что означает, что мы можем иметь дело с отдельными объектами, разделенными **. Во-вторых, синтаксически это просто немного менее сбивает с толку, чем предусматривают/поддерживают шаблон.


Python

Конечно, существуют другие способы сделать это, и одним из них является 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
1
ответ дан 23 November 2019 в 11:35

Другие вопросы по тегам:

Похожие вопросы: