Могу ли я выполнить «неглобальный» grep и получить только первое найденное совпадение для каждой строки ввода? - PullRequest
2 голосов
/ 26 января 2020

Я понимаю, что то, что я спрашиваю, можно выполнить с помощью awk или sed, я спрашиваю, как это сделать с помощью GREP.

С учетом следующего ввода:

.bash_profile
.config/ranger/bookmarks
.oh-my-zsh/README.md

Я хочу использовать GREP для получения:

.bash_profile
.config/
.oh-my-zsh/

В настоящее время я пытаюсь

grep -Po '([^/]*[/]?){1}'

Что приводит к выводу:

.bash_profile
.config/
ranger/
bookmarks
.oh-my-zsh/
README.md

Есть ли какой-нибудь простой способ использовать GREP для получения только первой соответствующей строки в каждой строке?

Ответы [ 3 ]

2 голосов
/ 26 января 2020

Я думаю, что вы можете использовать grep non / такие письма, как:

grep -Eo '^[^/]+'

На другом SO сайте есть еще один похожий вопрос с решением.

2 голосов
/ 26 января 2020

Вам вообще не нужно grep.

cut -d / -f 1
0 голосов
/ 26 января 2020

Опция -o говорит о необходимости печатать каждую подстроку, соответствующую вашему шаблону, вместо печати каждой соответствующей строки. Ваш текущий шаблон соответствует каждой строке, которая не содержит косой черты (опционально, включая завершающий sla sh); но легко переключиться на тот, который соответствует этому шаблону только в начале строки.

grep -o '^[^/]*' file

Обратите внимание на добавление ^ начала строки якоря и пропуск опции -P (который вы в действительности не использовали в любом случае), а также глупая ошибка новичка {1}.

(я должен добавить, что обычный grep не поддерживает скобки или повторы; grep -E будет поддерживать эти конструкции Вы можете переключиться на вариант POSIX BRE, который требует использования обратной метки sh для использования круглых или фигурных скобок в качестве метасимволов. Вы, вероятно, можете игнорировать эти детали и просто использовать grep -E везде, если только вам действительно не нужны функции grep -P хотя имейте в виду, что -P не является переносимым.)

...