Извлеките определенный текст между 2 символами в строке из текстового файла с помощью Python

#python

Вопрос:

Вот некоторые из содержимого моего файла журнала:

 2021.08.09.11.32.35.7795, General, connected?, connected, operation state, connecting, laser state, Standby, pulse picker trigger, internal, Amplifier LD current in mA, 0, PP Frequency in kHz, 10000, System Reset, 65535, Bust Mode, 1, Modelock, no, Oscillator Ready, not ready, Front-end Ready, ready, current in mA, 0, temperature in deg C, 26, power in mW, 37, Pulse Picker Frequency in kHz, 0, Laser ON Runtime in hour, 1894, Laser Head Humidity in %, 42, Laser Head Temperature in deg C, 26, Two Photon Diode in mV, 12, Laser Power in mW, 34, Error Code, 0, Laser FW Version, 7.4.6, TcpModbus protocol version, 1.1.4, state, Null, On, FALSE, Good, FALSE, Fast Blank, FALSE, Treating, FALSE, Error, FALSE, Error Detail, (No Error)
2021.08.09.11.32.45.7868, General, connected?, connected, operation state, connecting, laser state, Standby, pulse picker trigger, internal, Amplifier LD current in mA, 0, PP Frequency in kHz, 10000, System Reset, 65535, Bust Mode, 1, Modelock, no, Oscillator Ready, not ready, Front-end Ready, ready, current in mA, 0, temperature in deg C, 26, power in mW, 34, Pulse Picker Frequency in kHz, 0, Laser ON Runtime in hour, 1894, Laser Head Humidity in %, 42, Laser Head Temperature in deg C, 25, Two Photon Diode in mV, 11, Laser Power in mW, 34, Error Code, 0, Laser FW Version, 7.4.6, TcpModbus protocol version, 1.1.4, state, Null, On, FALSE, Good, FALSE, Fast Blank, FALSE, Treating, FALSE, Error, FALSE, Error Detail, (No Error)
2021.08.09.11.32.51.0936, General, connected?, connected, operation state, connecting, laser state, Standby, pulse picker trigger, internal, Amplifier LD current in mA, 0, PP Frequency in kHz, 10000, System Reset, 65535, Bust Mode, 1, Modelock, no, Oscillator Ready, not ready, Front-end Ready, ready, current in mA, 0, temperature in deg C, 26, power in mW, 37, Pulse Picker Frequency in kHz, 0, Laser ON Runtime in hour, 1894, Laser Head Humidity in %, 42, Laser Head Temperature in deg C, 26, Two Photon Diode in mV, 11, Laser Power in mW, 34, Error Code, 0, Laser FW Version, 7.4.6, TcpModbus protocol version, 1.1.4, state, Null, On, FALSE, Good, FALSE, Fast Blank, FALSE, Treating, FALSE, Error, FALSE, Error Detail, (No Error)
2021.08.09.11.32.55.8040, General, connected?, connected, operation state, connecting, laser state, Standby, pulse picker trigger, internal, Amplifier LD current in mA, 0, PP Frequency in kHz, 10000, System Reset, 65535, Bust Mode, 1, Modelock, no, Oscillator Ready, not ready, Front-end Ready, ready, current in mA, 0, temperature in deg C, 26, power in mW, 34, Pulse Picker Frequency in kHz, 0, Laser ON Runtime in hour, 1894, Laser Head Humidity in %, 41, Laser Head Temperature in deg C, 26, Two Photon Diode in mV, 11, Laser Power in mW, 34, Error Code, 0, Laser FW Version, 7.4.6, TcpModbus protocol version, 1.1.4, state, Null, On, FALSE, Good, FALSE, Fast Blank, FALSE, Treating, FALSE, Error, FALSE, Error Detail, (No Error)
 

Я хочу извлечь приведенные ниже данные в текстовый файл на основе приведенных выше данных:

 Date and Time               Amplifier LD current in mA   Two Photon Diode in mV
---------------             ---------------------------- ------------------------
2021.08.09.11.32.35.7795    0                            12
2021.08.09.11.32.45.7868    0                            11
2021.08.09.11.32.51.0936    0                            11 
2021.08.09.11.32.55.8040    0                            11
 

Кроме того, мне нужно извлечь и другие параметры, такие как:

  • ток в мА
  • температура в градусах C
  • мощность в МВт
  • Температура лазерной головки в градусах C
  • Мощность лазера в МВт
  • Быстрая Заготовка

В текстовом файле может быть до 10 000 строк данных. Я хотел бы знать, как лучше всего использовать скрипт Python для извлечения этих данных. Вот часть моего кода, которую я попробовал:

 file_path = r"Laser-20210809-113225.log" 
outFile = open("result.txt", "w")

with open(file_path, "r") as f:
    content = f.read()
    size = len(content)
    start =0
    for line in file_path:
        start = content.find(" Two Photon Diode in mV,",start)
        start = start if start != -1 else size
        end = content.find(", Laser Power in mW", start)
        end = end if end != -1 else size
        print(content[start 1:end])
        outFile.write(content[start 1:end])
        outFile.write("n")
        start = end   1
outFile.close()
 

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

Комментарии:

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

2. Ваши данные фактически представляют собой файл .csv — вы смотрели csv.reader ?

3. Логика сухого кода: 1. Прочитайте файл как pandas DF (с csv). 2. Пройдитесь по первой ячейке каждого столбца, если она совпадает с вашей поисковой «строкой» 3. Добавьте весь следующий столбец в новый DF; где столбец нового DF будет «строкой» поиска, а строки будут строками следующего столбца. #Только «Дата и время» всегда будет 0-м столбцом.

4. Спасибо, @SantiagoSquarzon. Я добавил PowerShell, подумав, что в PowerShell может быть возможное решение.

5. @Grismar спасибо за комментарий, на самом деле нет, я этого не делал. Буду разбираться в этом.

Ответ №1:

Ваш файл находится в указанном csv формате. Python имеет встроенную библиотеку для чтения csv-файлов: https://docs.python.org/3/library/csv.html

Я только что распечатал результаты, но, конечно, вы могли бы записать результаты в файл.

 import csv

with open(file_path, "r") as f:
    reader = csv.reader(f, delimiter=',')

    for row in reader:
        print(row[0], row[11], row[39])

 

Вы также можете указать заголовки столбцов, чтобы избежать уродливых цифр для доступа к правильным столбцам. Видишь https://docs.python.org/3/library/csv.html#csv.DictReader для подробностей.

Если вам нужны дополнительные функции и дополнительные манипуляции с данными, Pandas-отличная библиотека для такого типа данных. https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html это поможет вам получить данные.

Комментарии:

1. В настоящее время формат файла *.log, нужно ли мне конвертировать его в *.csv (или), как это будет работать?

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

Ответ №2:

Вероятно, самый простой способ сделать это-использовать .split() метод строк. В каждой итерации этого for вы можете использовать data=line.split(',') , чтобы разбить всю строку на несколько «сегментов», каждый из которых находится между парой запятых или в конце строки (вы можете заменить ',' любой другой символ/строку, чтобы разбить строки в соответствии с другими символами).

Используя этот подход, data[0] будет содержать время/дату, data[1] будет содержать строку «Общие», data[2] будет содержать «подключено?» и так далее.

Наконец, вам просто нужно записать data[] использование соответствующих индексов следующим образом: outFile.write(data[0] "," data[1] "," data[2])

Просто не забудьте проверить индекс столбцов, которые вы хотите сохранить, на основе входного файла, и используйте правильный индекс при записи.

Ответ №3:

Так как вы добавили powershell тег на свой вопрос, и я удалил его (чувствуя себя виноватым) Я думаю, я мог бы показать вам, как это можно сделать с помощью PS.

Это приведет к созданию объекта, которым вы можете легко манипулировать, например:

 PS /> $result.'Date and Time'
2021.08.09.11.32.35.7795
2021.08.09.11.32.45.7868
2021.08.09.11.32.51.0936
2021.08.09.11.32.55.8040

PS /> $result.'Date and Time'[2]
2021.08.09.11.32.51.0936

PS /> $result.'temperature in deg C'
26
26
26
26

PS /> $result.Where({$_.'Laser Head Temperature in deg C' -eq 26}) | Select-Object 'Date and Time','Laser Head Temperature in deg C'

Date and Time            Laser Head Temperature in deg C
-------------            -------------------------------
2021.08.09.11.32.35.7795 26                             
2021.08.09.11.32.51.0936 26                             
2021.08.09.11.32.55.8040 26      
 

Код будет выглядеть примерно так:

 $raw = @'
2021.08.09.11.32.35.7795, General, connected?, connected, operation state, connecting, laser state, Standby, pulse picker trigger, internal, Amplifier LD current in mA, 0, PP Frequency in kHz, 10000, System Reset, 65535, Bust Mode, 1, Modelock, no, Oscillator Ready, not ready, Front-end Ready, ready, current in mA, 0, temperature in deg C, 26, power in mW, 37, Pulse Picker Frequency in kHz, 0, Laser ON Runtime in hour, 1894, Laser Head Humidity in %, 42, Laser Head Temperature in deg C, 26, Two Photon Diode in mV, 12, Laser Power in mW, 34, Error Code, 0, Laser FW Version, 7.4.6, TcpModbus protocol version, 1.1.4, state, Null, On, FALSE, Good, FALSE, Fast Blank, FALSE, Treating, FALSE, Error, FALSE, Error Detail, (No Error)
2021.08.09.11.32.45.7868, General, connected?, connected, operation state, connecting, laser state, Standby, pulse picker trigger, internal, Amplifier LD current in mA, 0, PP Frequency in kHz, 10000, System Reset, 65535, Bust Mode, 1, Modelock, no, Oscillator Ready, not ready, Front-end Ready, ready, current in mA, 0, temperature in deg C, 26, power in mW, 34, Pulse Picker Frequency in kHz, 0, Laser ON Runtime in hour, 1894, Laser Head Humidity in %, 42, Laser Head Temperature in deg C, 25, Two Photon Diode in mV, 11, Laser Power in mW, 34, Error Code, 0, Laser FW Version, 7.4.6, TcpModbus protocol version, 1.1.4, state, Null, On, FALSE, Good, FALSE, Fast Blank, FALSE, Treating, FALSE, Error, FALSE, Error Detail, (No Error)
2021.08.09.11.32.51.0936, General, connected?, connected, operation state, connecting, laser state, Standby, pulse picker trigger, internal, Amplifier LD current in mA, 0, PP Frequency in kHz, 10000, System Reset, 65535, Bust Mode, 1, Modelock, no, Oscillator Ready, not ready, Front-end Ready, ready, current in mA, 0, temperature in deg C, 26, power in mW, 37, Pulse Picker Frequency in kHz, 0, Laser ON Runtime in hour, 1894, Laser Head Humidity in %, 42, Laser Head Temperature in deg C, 26, Two Photon Diode in mV, 11, Laser Power in mW, 34, Error Code, 0, Laser FW Version, 7.4.6, TcpModbus protocol version, 1.1.4, state, Null, On, FALSE, Good, FALSE, Fast Blank, FALSE, Treating, FALSE, Error, FALSE, Error Detail, (No Error)
2021.08.09.11.32.55.8040, General, connected?, connected, operation state, connecting, laser state, Standby, pulse picker trigger, internal, Amplifier LD current in mA, 0, PP Frequency in kHz, 10000, System Reset, 65535, Bust Mode, 1, Modelock, no, Oscillator Ready, not ready, Front-end Ready, ready, current in mA, 0, temperature in deg C, 26, power in mW, 34, Pulse Picker Frequency in kHz, 0, Laser ON Runtime in hour, 1894, Laser Head Humidity in %, 41, Laser Head Temperature in deg C, 26, Two Photon Diode in mV, 11, Laser Power in mW, 34, Error Code, 0, Laser FW Version, 7.4.6, TcpModbus protocol version, 1.1.4, state, Null, On, FALSE, Good, FALSE, Fast Blank, FALSE, Treating, FALSE, Error, FALSE, Error Detail, (No Error)
'@ -split 'r?n'

$i=0

$result = $raw | ForEach-Object {

    $arr = $_ -split ',' -ne ''
    $col, $val = $arr[2..($arr.Length-1)].where({
        if($i = -not $i){$_}
    },'Split')
    
    $out = [ordered]@{}
    $out.Add('Date and Time',$arr[0].Trim())
    $out.Add('General?',$arr[1].Trim())

    for($z=0;$z -lt [math]::Max($col.Count,$val.Count);$z  )
    {
        $out.Add($col[$z].Trim(),$val[$z].Trim())
    }

    [pscustomobject]$out
}
 

Примечание: $raw Переменная предназначена только для проверки кода, однако, поскольку вы читаете .log файл, вы должны прочитать его с помощью Get-Content :

 $raw = Get-Content 'absolute/path/to/Laser-20210809-113225.log'
 

Наконец, вот как $result выглядит объект при использовании Out-GridView :

$результат|Выход-Представление сетки

Комментарии:

1. Большое вам спасибо, однако у меня возникли проблемы, я использовал Windows PowerShell для его выполнения, и когда я его выполняю, я не получаю никаких результатов. Должен ли я использовать какую-либо команду в конце, которую я пропустил, чтобы увидеть здесь. Извините за беспокойство и большое спасибо за действительно необходимую помощь.

2. @SHYAMTHILLAINATHAN вы видели, заполнена ли переменная $result ? Просто сделайте $result это и нажмите enter в консоли.

Ответ №4:

Наконец-то это сработало, спасибо всем за вашу помощь, очень ценю:

 import pandas as pd
import csv
import time
import datetime

pd.set_option('display.max_rows',10000)

timestr = time.strftime("%Y%m%d-%H%M%S")
file_start = r".output_"
extension = ".csv"

file_name = file_start   timestr   extension

outFile = open(file_name, "w")
df = pd.read_csv(r'C:Userssthilla1Downloads2021-08-0911-32-25Laser-20210809-113225.csv', usecols = [0,25,26], low_memory = True)
outFile.write(str(df))
outFile.close()
 

Ответ №5:

Для получения даты вы можете использовать регулярные выражения:

 import re

text = "2021.08.09.11.32.35.7795 text text text 2001.02.01.12.35.55.7795"

regex_pattern = "[0-9]{4}(?:.[0-9]{2}){5}.[0-9]{4}"

date_list = re.findall(regex_pattern, text) #to get many ones

date = re.search(regex_pattern, text)[0] #to get only one

print(date_list)
print("-------")
print(date)

 

Результат:

 ['2021.08.09.11.32.35.7795', '2001.02.01.12.35.55.7795']
-------
2021.08.09.11.32.35.7795