текст извлечения из файла с помощью терминала?

Я хочу обработать тело текста и извлечь целое число из определенного положения в тексте, но я не уверен, как описать то 'особое положение'. Регулярные выражения действительно смущают меня. Я потратил (потратил впустую) пару часов, читая учебные руководства, и я чувствую себя не ближе к ответу :(

Существует набор текста, который может или не может включать целые числа (что я не хочу) и затем существует строка, которая всегда содержит

id_ad=1929170&action

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

Так интуитивно я знаю, что просто хочу проигнорировать все до (и включая) id_ad= и проигнорируйте все после (и включая) &action и меня оставят с целым числом, которое я хочу. И я знаю, что могу использовать регулярные выражения для достижения этого. Но я, может казаться, не понимаю это.

Я хотел бы сделать это как один лайнер от терминала, если это возможно.

1
задан 7 November 2014 в 10:07

4 ответа

Не так один лайнер (хотя команда для выполнения его является одним лайнером :)), но вот опция Python:

#!/usr/bin/env python3
import sys
file = sys.argv[1]

with open(file) as src:
    text = src.read()

starters = [(i+6, text[i:].find("&action")+i) for i in range(len(text)) if text[i:i+6] == "id_ad="]
if len (starters) > 0:
    for item in starters:
        print(text[item[0]:item[1]])

Сценарий сначала перечисляет все случаи (индексы) (запуск) строка "id_ad = ", в сочетании с (концом) строка" &action". Затем это печатает все, что является между теми "маркерами".

Извлеченный из подготовленного файла:

"Я хочу обработать тело текста и извлечь целое число из определенного положения в тексте, но я не уверен, как описать то 'особое положение'. Регулярные выражения действительно смущают меня. Я потратил (потратил впустую) пару часов, читая учебные руководства, и я чувствую себя не ближе к ответу :( Существует набор текста, который может или не может включать целые числа (что я не хочу) и затем существует строка, которая всегда содержит id_ad=1929170&action существует набор текста, который может или не может включать целые числа (что я не хочу) и затем существует строка, которая всегда содержит id_ad=1889170&action и затем сопровождаемый набором мусора, о котором я не забочусь, снова это может или не может включать одно или несколько целых чисел. Существует набор текста, который может или не может включать целые числа (что я не хочу) и затем существует строка, которая всегда содержит id_ad=1889170&action и затем сопровождаемый набором мусора, о котором я не забочусь, снова это может или не может включать одно или несколько целых чисел. Существует набор текста, который может или не может включать целые числа (что я не хочу) и затем существует строка, которая всегда содержит id_ad=1929990&action"

Результат:

1929170
1889170
1889170
1929990

Как использовать

Вставьте сценарий в пустой файл, сохраните его как extract.py выполните его командой:

python3 <script> <file>

Примечание:

Если существует только одно возникновение в текстовом файле, сценарий может быть намного короче:

#!/usr/bin/env python3
import sys
file = sys.argv[1]

with open(file) as src:
    text = src.read()
print(text[text.find("id_ad=")+6:text.find("&action")])
2
ответ дан 3 December 2019 в 06:26

Например:

 egrep "id_ad=[[:digit:]]+&action" file.txt |  tr "=&" "  " | cut -d " " -f2 

..., но я уверен, что существуют более изящные пути;-).

Шаг за шагом:

egrep "id_ad=[[:digit:]]+&action" file.txt 

сканирование file.txt для шаблона (регулярное выражение), которое составлено литералом id_ad=, сопровождаемый 1 или более цифрами (значение [[:digit:]]+, сопровождаемый литералом &action. Отправьте вывод в стандартный вывод.

tr "=&" "  " 

преобразовывает символы "=" и "&"; в два пробелов.

cut -d " " -f2

печатают второе поле (разделенное пробелом) из стандартного входа.

2
ответ дан 10 November 2019 в 08:08

С помощью sed:

sed 's/id_ad=\(.*\)&action/\1/' filename

Объяснение:

Приведенная выше команда возвращает любые строки (.*) между двумя словами START (id_ad=) и словом END (&action) в имени файла.
\(...\) Используется для захвата групп. \( является началом группы захвата и заканчивается \). А с помощью \1 мы печатаем его групповой индекс (у нас есть одна группа захвата)

Лучшая команда sed для вышеуказанного решения может быть такой:

sed 's/^id_ad=\([0-9]*\)&action/\1/' filename

^ Start линии.
[0-9]*: любое число с 0 или более экземплярами.
Подробнее о команде sed см. В

С grep:

Объяснение:

grep -Po '(?<=id_ad=)[0-9]*(?=&action)' filename

От man grep:

-o, --only-matching
      Print only the matched (non-empty) parts of a matching line,
      with each such part on a separate output line.
-P, --perl-regexp
      Interpret PATTERN as a Perl compatible regular expression (PCRE)

Возвращает любое число с 0 или более вхождениями ([0-9]*) между двумя словами START (id_ad=) и END (&action) в имени файла.

(?<=pattern): позитивный взгляд назад. Пара круглых скобок, с открывающей скобкой, за которой следует знак вопроса, символ «меньше чем» и знак равенства.

(?<=id_ad=)[0-9]* (положительный вид сзади) соответствует 0 или более появлений чисел, которые следуют после id_ad= в имени файла.

(?=pattern): положительный прогноз: конструкция «положительный взгляд» представляет собой пару круглых скобок, с открывающей скобкой, за которой следует знак вопроса и знак равенства.

[0-9]*(?=&action): (положительный прогноз) сопоставляет 0 или более вхождений чисел, за которыми следует шаблон (&action), не делая шаблон (&action) частью соответствия.
Подробнее о Lookahead и Lookbehind

Дополнительные ссылки:
Расширенные темы Grep ]
GREP для дизайнеров

2
ответ дан 10 November 2019 в 08:08

Другой ответ Python через re модуль. Пример украден от сообщения Jacob.

script.py

#!/usr/bin/python3
import sys
import re
file = sys.argv[1]
L = []                                                  # Declare an empty list
with open(file) as src:
    for j in src:                                       # iterate through all the lines
        for i in re.findall(r'id_ad=(\d+)&action', j):  # extracts the digits which was present in-between `id_ad=` and `&action` strings.
            L.append(i)                                 # Append the extracted digits to the already declared empty list L. 
    for f in L:                                         # Iterate through all the elements in the list L
        print(f)                                        # Print each element from the list L in a separate new line.

Запустите вышеупомянутый скрипт как,

python3 script.py /path/to/the/file

Пример:

$ cat fi
I want to process the body of text and extract an integer from a specific position in the text, but I'm not sure how to describe that 'particular position'. Regular expressions really confuse me. I spent (wasted) a couple hours reading tutorials and I feel no closer to an answer :( There's a bunch of text which may or may not include integers (that I don't want) and then there's a line that always contains

 id_ad=1929170&action There's a bunch of text which may or may not include integers (that I don't want) and then there's a line that always contains id_ad=1889170&action and then followed by a bunch of garbage I don't care about, again it may or may not include one or more integers. There's a bunch of text which may or may not include integers (that I don't want) and then there's a line that always contains

 id_ad=1889170&action and then followed by a bunch of garbage I don't care about, again it may or may not include one or more integers. There's a bunch of text which may or may not include integers (that I don't want) and then there's a line that always contains id_ad=1929990&action

$ python3 script.py ~/file
1929170
1889170
1889170
1929990
1
ответ дан 3 December 2019 в 06:26

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

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