2

Я пытаюсь использовать расширенный параметр регулярного выражения в grep, чтобы отфильтровать из файлов, строки, которые имеют следующий формат строки в начале строки.

any-non-space-char:      *

Я предполагал, что следующая команда будет добиваться цели; тем не менее, он просто распечатал все строки из двух файлов, которые подобраны подстановочным знаком.


~/tmp > cat * | grep -v -E "^\S+:.{6}\*"
hi
test1      blah, blah, blah:      * blah, blah, blah"
test:      * blah, blah, blah:      * blah, blah, blah
sd
hi
temp:      * blah, blah, blah:      * blah, blah, blah"
temp2:     blah, blah, blah:      * blah, blah, blah
sd
~/tmp >

Кстати, я псевдоним grep для 'grep --color=auto' , поэтому команда действительно выделяет соответствующие строки в соответствии с регулярным выражением, которые являются test: * в строке 3 и temp: * в строке 6 в приведенном выше выводе. Тем не менее, эти совпадающие строки напечатаны на экране, чего я не ожидал.

Содержимое двух файлов:


~/tmp > ls -l
total 8
-rw-rw-r-- 1 pmn ccusers 116 Dec 11 09:22 1
-rw-rw-r-- 1 pmn ccusers 116 Dec 11 09:23 2
~/tmp >

~/tmp > cat 1
hi
test1      blah, blah, blah:      * blah, blah, blah"
test:      * blah, blah, blah:      * blah, blah, blah
sd
~/tmp >

~/tmp > cat 2
hi
temp:      * blah, blah, blah:      * blah, blah, blah"
temp2:     blah, blah, blah:      * blah, blah, blah
sd
~/tmp >

Кстати, следующее похоже на то, что я ожидаю:


~/tmp > cat * | grep -v -E ":.{6}*"
hi
sd
hi
sd
~/tmp >

Которые убрали строки


test1      blah, blah, blah:      * blah, blah, blah"
test:      * blah, blah, blah:      * blah, blah, blah
temp:      * blah, blah, blah:      * blah, blah, blah"
temp2:     blah, blah, blah:      * blah, blah, blah

(он также удалил строки 1 и 4 выше, что не то, что я хочу - следовательно, эта команда grep не будет работать для меня).

Я знаю, как заставить это работать на PERL; однако по определенным причинам я могу использовать только grep, awk или sed.

Как мне заставить это работать?


@PsychoData

Спасибо за ваш ответ. Я боюсь, что команда не добилась цели. Ваша команда вернула следующее

~/tmp > cat * | grep -v -E "^[^\S]+:.{6}\*"  
hi  
sd  
hi  
sd  
~/tmp >

что совпадает с выводом, возвращаемым grep -v -E ":.{6}*" в моем вопросе, что, однако, не то, что я хотел. Я хотел, чтобы команда вывела следующий вывод:

hi  
test1      blah, blah, blah:      * blah, blah, blah"  
sd  
hi  
temp2:     blah, blah, blah:      * blah, blah, blah  
sd

ИМХО, вы удалили следующие строки, потому что ^[^\S]+: выполняет жадное совпадение, сопоставляя как можно большую часть строки, что, как вы можете видеть, до самого правого ' * ' в следующих строках.

test1      blah, blah, blah:      * blah, blah, blah"  
test:      * blah, blah, blah:      * blah, blah, blah  
temp:      * blah, blah, blah:      * blah, blah, blah"  
temp2:     blah, blah, blah:      * blah, blah, blah

Кстати, обратите внимание, что между каждой парой : и * есть ровно 6 пробелов. Я думаю, что форматирование делает это трудно заметным.

2 ответа2

1

попробуйте grep -v -E "^[^\S]+:.{6}\*"

Хорошо. Итак, что я делаю с этим, так это говорю, что хочу, чтобы каждая строка не содержала следующий шаблон, и включал расширенные выражения:

match the start of a line, then [anything EXCEPT whitespace] at least once,then a colon, then 6 characters, then an asterisk

все, что не соответствует этому шаблону, будет показано

1

В расширенных регулярных выражениях нет способа сделать не жадное совпадение. Однако вы можете легко сделать это с помощью PCRE:

$ grep -hvP "^[^\s]+?:\s+\*" *
hi
test1      blah, blah, blah:      * blah, blah, blah"
sd
hi
temp2:     blah, blah, blah:      * blah, blah, blah
sd

Вам не нужно cat за файлами, grep может открыть их напрямую. Опция -h витки печати имени файла (необходимо , если не cat ИНГ) и -P включает PCREs. Затем вы ищете один или несколько непробельных символов в начале строки ^[^\s]+? , за которым следуют : один или несколько пробелов (\s+) и, наконец, * (вам нужно экранировать * иначе он рассматривается как квантификатор).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .