извлечь строку на основе скобок с помощью sed - PullRequest
2 голосов
/ 03 октября 2019

Я хочу извлечь строку, которая находится за скобками, используя sed. Пример, следующий - вывод / proc / mdstat, и у него есть неисправный диск, который обозначается (F).
cat /proc/mdstat | grep 'F' md2 : active raid1 nvme0n1p3[0](F) nvme1n1p3[1]

Я хочу извлечь диск nvme0n1p3 с суффиксом (F) рядом с ним. Я попытался с awk и cut, но положение вышедших из строя дисков меняется, и в этом случае awk и cut не будут работать. Может ли кто-нибудь помочь мне в этом, поскольку регулярные выражения кажутся мне сложными.

Ответы [ 2 ]

1 голос
/ 03 октября 2019

Вы можете использовать один вызов awk (обратите внимание, что вам не нужно cat, просто передайте файл awk напрямую):

awk -F'[][():[:space:]]+' '/\(F\)/{print $4}' /proc/mdstat

-F'[][():[:space:]]+' устанавливает полеразделитель для регулярного выражения, который соответствует 1 или более ], [, (, ), : или пробельным символам. Таким образом, поля, которые вы получите, будут [md2, active, raid1, nvme0n1p3, 0, F, nvme1n1p3, 1], и, как вы видите, ваше значение находится в поле 4.

Я также добавил проверку скобок вокруг F, возможно, это приведет к поиску строкибезопаснее.

Онлайн тест :

s="some line 1
md2 : active raid1 nvme0n1p3[0](F) nvme1n1p3[1]
last line"
awk -F'[][():[:space:]]+' '/\(F\)/{print $4}' <<< "$s"
# => nvme0n1p3
1 голос
/ 03 октября 2019

Вот решение, использующее sed в расширенном режиме регулярного выражения:

echo "md2 : active raid1 nvme0n1p3[0](F) nvme1n1p3[1]" |
    sed -E 's/^.* (\S+)\[[[:digit:]]+\]\(F\).*$/\1/'

Это выводит:

nvme0n1p3

Вот объяснение используемого шаблона:

^                     from the start of the input
    .*                consume anything, up until the last
    [ ]               single space, followed by
    (\S+)             series of non whitespace characters (captured)
    \[[[:digit:]]+\]  which are followed by '[0]', a number in square brackets
    \(F\)             followed by '(F)'
    .*                then consume the rest of the input
$                     end of input

Затем мы заменяем на \1, то есть количество (\S+), захваченное из шаблона регулярных выражений, которое должно быть тем, что вы хотите найти.

...