2017-02-15 12 views
1

Я хочу, чтобы правила фильтрации были настроены в /etc/lvm/lvm.conf, например filter = [ "r|/dev/sda|" ]. Я хочу sed, чтобы вернуть "r|/dev/sda|". Так что я попробовал следующий сценарий:Не удалось совместить символы без пробелов с символьным классом

echo ' filter = [ "r|/dev/sda|" ] ' | sed -r 's:^\s*filter\s*=\s*\[\s*([^\s]+)\s*\]:\1:g'

Но это не сработало, то сценарий вернулся filter = [ "r|/dev/sda|" ]. Я пробовал несколько тегов регулярных выражений, группа была правильно подобрана.

Однако, если я заменяю [^\s]+ на .+, он работает.

Не имеет значения [^\s]+более одного символа пробела?

Любая идея, пожалуйста?

+1

Этих Shorthands не может быть использован внутри отрицаний выражений брекета. '[^ [: space:]]' будет работать. –

+0

Да! спасибо, спасибо, большое спасибо @ WiktorStribiżew – vesontio

+0

, если вы в порядке с 'grep': попробуйте фильтр' grep -oP '. * \ K ". *?"' inputfile' –

ответ

3

Acc. в regular-expressions.info:

Одним из ключевых синтаксической разницы в том, что обратный слэш НЕ метасимволом в выражении скобки POSIX. Таким образом, в POSIX регулярное выражение [\d] соответствует \ или d.

Так что вам нужно заменить [^\s][^[:space:]] с (любой символ, кроме пробела).

Example:

echo ' filter = [ "r|/dev/sda|" ] ' | sed -E 's:^\s*filter\s*=\s*\[\s*([^[:space:]]+)\s*\]:\1:g' 

Выход: "r|/dev/sda|"

1

В случае Grep решение приемлемо:

grep -oP 'filter.*\K".*?"' inputfile 
1

Альтернативно проще и короче, чем [^[:space:]] вы можете сделать с \S+ без использования скобок []

\S означает не пробельного CHAR

echo ' filter = [ "r|/dev/sda|" ] ' | sed -r 's:^\s*filter\s*=\s*\[\s*(\S+)\s*\]:\1:g' 

https://ideone.com/PxDX1Q

+0

Спасибо @Grisza, Да, действительно, это тоже хорошее решение. – vesontio