Как я могу найти несколько шаблонов с помощью grep и распечатать их в одной строке?

Судя по вашему (небольшому) образцу сообщений smartctl выше, их части в основном разделены "<пробел> <чем угодно, кроме строчной буквы>" ( кроме поля "# nnn" в самом начале строки).

sed может помочь разделить части:

$ smartctl_output="\                                           
# 1 Short offline Completed without error 00% 7264 -
# 2 Short offline Completed without error 00% 7240 -
# 1 Short offline Completed: read failure 20% 717 555027747"

$ csv="$( sed 's/ //; s/ \([^[:lower:]]\)/,\1/g' <<< "$smartctl_output" )"

$ echo "$csv"
#1,Short offline,Completed without error,00%,7264,-
#2,Short offline,Completed without error,00%,7240,-
#1,Short offline,Completed: read failure,20%,717,555027747

Если это то, что вы хотите, теперь вы можете заполнить свой массив, как вы это делали с HDDinfo.

[update]

Вот объяснение части sed , которая выполняет разбиение: программа sed состоит из двух частей, которые я поместил в одну линию. Вот расширенная версия:

sed '
    s/ //
    s/ \([^[:lower:]]\)/,\1/g
'

Программа sed работает с каждой строкой ввода: она считывает одну строку, применяет набор преобразований и печатает строку.Затем он начинается со следующей строки до тех пор, пока больше не останется строк для чтения.

Здесь первая sed команда s / // удаляет первый пробел, объединяющий «#» и следующее число.

Затем вторая команда sed s / \ ([^ [: lower:]] \) /, \ 1 / g выполняет поиск в начале каждого поля (как определено на "<пробел> <все, кроме строчных букв>") и заменяет пробел двоеточием. \ 1 относится к регулярному выражению в круглых скобках « \ ([^ [: lower:]] \) », которое представляет первый символ следующего поля.

Оставшаяся часть представляет собой тест: вместо того, чтобы передать sed содержимое файла или вывод команды, я передал ему переменную smartctl_output (строка, сделанная ваших образцов), и я присвоил результат переменной csv .

[обновление №2]

Теперь кажется, что поля разделены двумя или более пробелами. Это даже проще, чем раньше. Команда sed преобразуется в:

sed 's/  \+/,/g'

Что означает: заменить все серии из двух или более пробелов двоеточием.

1
17.03.2017, 19:44
3 ответа

С column:

COLUMN(1)                 BSD General Commands Manual                COLUMN(1)

NAME
     column -- columnate lists

SYNOPSIS
     column [-tx] [-c columns] [-s sep] [file ...]

DESCRIPTION
     The column utility formats its input into multiple columns.  Rows are
     filled before columns.  Input is taken from file operands, or, by
     default, from the standard input.  Empty lines are ignored.

Например (с бесплатным бесполезным использованием cat, чтобы продемонстрировать, что вы можете направить вывод grep в column):

$ cat example
Fuzzy
wuzzy
was
a
bear
$ cat example | column
Fuzzy   wuzzy   was a   bear
2
27.01.2020, 23:19

Используйте sed для копирования частей строки, соответствующих шаблону, на вывод, используя группы захвата.

sed -r -n 's/.*(.{0,5}patternA).*(.{0,5}patternB.{0,5}).*(patternC.{0,5}).*/\1 \2 \3/p' filename.txt

Это предполагает, что шаблоны всегда расположены в таком порядке в строках.

2
27.01.2020, 23:19

Если вы знаете, что все 3 поля всегда существуют, вы можете попробовать следующее с «вставить»

grep -P -o ".{0,5}patternA|.{0,5}patternB.{0,5}|patternC.{0,5}" filename.txt | paste - - -

3
27.01.2020, 23:19

Теги

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