我可以执行 'non-global' grep 并仅捕获为每行输入找到的第一个匹配项吗?

Can I perform a 'non-global' grep and capture only the first match found for each line of input?

我知道我的要求可以使用 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 仅获取每行中第一个匹配的字符串?

你根本不需要 grep

cut -d / -f 1

我认为你可以 grep 非 / 字母,例如:

grep -Eo '^[^/]+'

在另一个 SO 站点上有另一个类似的 question 解决方案。

-o 选项表示打印与您的模式匹配的每个子字符串,而不是打印每个匹配行。您当前的模式匹配每个不包含斜线的字符串(可选地包括尾部斜线);但很容易切换到仅在行首匹配此模式的模式。

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

注意添加了 ^ 行锚点开头,并省略了 -P 选项(无论如何你都没有真正使用它)以及愚蠢的初学者错误 {1}.

(我应该补充一点,普通 grep 不支持括号或重复;grep -E 会很好地支持这些结构,你可以切换到 toe POSIX BRE 变体需要一个反斜杠来使用圆括号或花括号作为元字符。你可以忽略这些细节,只在任何地方使用 grep -E,除非你真的需要 grep -P 的功能,但也要注意 -P不可携带。)