Извлечь несколько подходящих подстрок из строки, используя скрипт bash - PullRequest
0 голосов
/ 12 апреля 2020

Я хотел проанализировать журналы тестов пользовательского интерфейса, чтобы извлечь среднюю продолжительность отдельных тестов, которые обозначены OS Signpost Duration. Мне удалось извлечь строки, содержащие OS Signpost Duration из нескольких файлов журнала.

/Users/username/Projects/uitest/uitestUITests/uitestUITests.swift:44: Test Case '-[uitestUITests.uitestUITests test2]' measured [OS Signpost Duration (test 2 tapped), s] average: 4.001, relative standard deviation: 0.017%, values: [4.001285, 4.000268, 4.002284, 4.000665, 4.001234], performanceMetricID:com.apple.dt.XCTMetric_OSSignpost-test 2 tapped.duration, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.000, maxStandardDeviation: 0.000 /Users/username/Projects/uitest/uitestUITests/uitestUITests.swift:33: Test Case '-[uitestUITests.uitestUITests testExample]' measured [OS Signpost Duration (test 1 tapped), s] average: 2.001, relative standard deviation: 0.017%, values: [2.001135, 2.001209, 2.000610, 2.000730, 2.000262], performanceMetricID:com.apple.dt.XCTMetric_OSSignpost-test 1 tapped.duration, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.000, maxStandardDeviation: 0.000 /Users/username/Projects/uitest/uitestUITests/uitestUITests.swift:54: Test Case '-[uitestUITests.uitestUITests testLaunchPerformance]' measured [OS Signpost Duration (AppLaunch), s] average: 0.463, relative standard deviation: 12.413%, values: [0.539167, 0.385542, 0.463822, 0.512382, 0.415148], performanceMetricID:com.apple.dt.XCTMetric_OSSignpost-AppLaunch.duration, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.000, maxStandardDeviation: 0.000 /Users/username/Projects/uitest/uitestUITests/uitestUITests.swift:44: Test Case '-[uitestUITests.uitestUITests test2]' measured [OS Signpost Duration (test 2 tapped), s] average: 4.001, relative standard deviation: 0.018%, values: [4.000617, 4.000975, 4.002513, 4.000692, 4.001549], performanceMetricID:com.apple.dt.XCTMetric_OSSignpost-test 2 tapped.duration, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.000, maxStandardDeviation: 0.000 /Users/username/Projects/uitest/uitestUITests/uitestUITests.swift:33: Test Case '-[uitestUITests.uitestUITests testExample]' measured [OS Signpost Duration (test 1 tapped), s] average: 2.001, relative standard deviation: 0.020%, values: [2.000350, 2.001232, 2.000362, 2.001022, 2.000259], performanceMetricID:com.apple.dt.XCTMetric_OSSignpost-test 1 tapped.duration, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.000, maxStandardDeviation: 0.000 /Users/username/Projects/uitest/uitestUITests/uitestUITests.swift:54: Test Case '-[uitestUITests.uitestUITests testLaunchPerformance]' measured [OS Signpost Duration (AppLaunch), s] average: 0.416, relative standard deviation: 15.702%, values: [0.495147, 0.413174, 0.378256, 0.478277, 0.317015], performanceMetricID:com.apple.dt.XCTMetric_OSSignpost-AppLaunch.duration, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.000, maxStandardDeviation: 0.000 /Users/username/Projects/uitest/uitestUITests/uitestUITests.swift:44: Test Case '-[uitestUITests.uitestUITests test2]' measured [OS Signpost Duration (test 2 tapped), s] average: 4.002, relative standard deviation: 0.010%, values: [4.002300, 4.001725, 4.001849, 4.001945, 4.001093], performanceMetricID:com.apple.dt.XCTMetric_OSSignpost-test 2 tapped.duration, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.000, maxStandardDeviation: 0.000 /Users/username/Projects/uitest/uitestUITests/uitestUITests.swift:33: Test Case '-[uitestUITests.uitestUITests testExample]' measured [OS Signpost Duration (test 1 tapped), s] average: 2.000, relative standard deviation: 0.020%, values: [2.001171, 2.000079, 2.000173, 2.000237, 2.000132], performanceMetricID:com.apple.dt.XCTMetric_OSSignpost-test 1 tapped.duration, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.000, maxStandardDeviation: 0.000 /Users/username/Projects/uitest/uitestUITests/uitestUITests.swift:54: Test Case '-[uitestUITests.uitestUITests testLaunchPerformance]' measured [OS Signpost Duration (AppLaunch), s] average: 0.598, relative standard deviation: 31.034%, values: [0.888853, 0.613004, 0.690106, 0.402929, 0.395714], performanceMetricID:com.apple.dt.XCTMetric_OSSignpost-AppLaunch.duration, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.000, maxStandardDeviation: 0.000

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

  1. [Продолжительность указателя ОС (тест 2 нажат), с] среднее: 4.001
  2. [Продолжительность указателя ОС ( тест 1 постучал), с] среднее: 2,001
  3. [OS Signpost Duration (AppLaunch), с] среднее: 0,463

Теперь то, что я хотел сделать, это извлечь что-то для повторения как словарь (или hashmap) (игнорируя дубликаты)

[
 "test 2 tapped": 4.001,
 "test 1 tapped": 2.001,
 "AppLaunch"    : 0.463
]

Я хочу извлечь таким образом, чтобы я мог перебирать переменную и отправлять эти данные в API. Любая помощь будет оценена ? Спасибо:)

1 Ответ

0 голосов
/ 12 апреля 2020

Возможно, вы захотите создать небольшой скрипт:

#!/bin/bash

FILE_PATH='/tmp/tmp'

parsed_data=`\
    sed -e 's/\(\/[^:/]*\)*:[0-9]*:/\n/g' $FILE_PATH | \
    sed -e 's/^.*Duration (\(.*\)).*average: \([0-9.]\+\).*$/\2 \1/g' -e '/^$/d'
`

while read avg name; do
    printf "name: $name\tavg: $avg\n"
done <<< $parsed_data

Объяснение

1-й sed предназначен только для разделения ввода по строкам, чтобы иметь только 1 результат в строке :
* \(\/[^:/]*\)* ➤ Это захватывает путь (например, "/User/My/Path/foo.sh"):
+ \/ - это единственный sla sh (например, /)
+ [^:/]* - это все, что не содержит sla sh или двоеточие (например, User)
+ \(...\)* используется для захвата группы и повторения столько раз, сколько возможно
* :[0-9]*: ➤ Это соответствует номерам строк, присутствующим после пути (например, ": 44:")
* \n ➤ И затем мы заменим все это новой строкой

Так что в В конце концов, это разделяет ввод для каждого имени файла

Дополнительная операция (/^$/d) используется для удаления пустых строк


2nd sed выделяет интересующие нас детали:

  • ^.*Duration Все, что от начала линии до "Продолжительность"
  • .*average: ➤ Все до "среднего":
  • \([0-9.]\+\) ➤ Любое число ([0-9]) или точка (.). Обратите внимание, что мы также фиксируем эту часть: это наше среднее значение.
  • .*$ ➤ Все до конца строки

Итак, на этом этапе мы сопоставили всю строку, и мы захватили заголовок и среднее.


Теперь нам нужно просто заменить все это захваченной группой:
- \2 \1 ➤ Это число (\2) и заголовок (\1).

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

Итак, на данный момент у нас есть строка, которая выглядит следующим образом:

12.2345 My small title
15.2345 My loong long title
62.2345 My title

Тогда нам просто нужно вызвать read в каждой строке:

read avg name

Здесь read хранит 1-е слово (то есть среднее) в переменной avg, и оставшаяся часть (заголовок) в переменной name

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...