通过管道将内容导入 Grep

通过管道将内容导入 Grep

我有一个命令,可以以文本形式输出我所属的组:

$ groups
dbadmin hdpcl3 stargroup9 jorgesgroup ...

我想检查一下此输出是否包含我想要的组。我试过:

$ groups > mygroups.txt
$ grep -R "stargroup9" mygroups.txt
stargroup9

这可行,但我想在一行中完成此操作而不创建临时文件。一种简洁的方法是知道如何:

$ groups | grep -R "stargroup9" .

其中 '.' 表示将输入放在此处,例如R 的 dplyr/magrittr句法:

> my_species %>% filter(iris, Species == .)

答案1

要使grep进程成为其 stdin,您应该在不使用文件(或目录)名称作为操作数的情况下调用它。这是一个简单但不是最佳的解决方案:

组 | grep "stargroup9"

这样更好:

groups | grep -E '(^| )stargroup9( |$)'

其中(^| )匹配行首或空格字符,( | $)匹配空格字符或行尾;因此例如名为的组stargroup98765不匹配。

-E使用扩展正则表达式。作为基本正则表达式(不带-E),模式应如下所示:(\(^\| \)stargroup9\( \|$\)并且应使用单引号)。我之所以使用,-E是因为这种方式的模式更具可读性。

您可能会遇到一个建议,其模式类似于\bstargroup9\b,其中\b锚定在单词边界(或grep -w stargroup9是等效的)。请勿在此处使用此方法。问题是组名可以包含,-但此字符(就此而言\b)分隔单词。实际上,该模式可以匹配名为 的组stargroup9-123foo。如果您在这个组中但不在 中stargroup9,则模式\b会误导您(同样适用于grep -w)。

在脚本中,您可能希望检查自己是否是成员,而不打印 的任何输出grep。使用-q使命令安静。它的退出状态就足够了。示例:

groups | grep -qE '(^| )stargroup9( |$)' && do_something
if groups | grep -qE '(^| )stargroup9( |$)'; then …

你的方法有什么问题?

grep -R递归读取指定目录下的文件。如果仅指定文件(即非目录),则该选项不会发生任何变化。

如果grep要从其 stdin 读取(如 中所示groups | grep …),则不能指定任何操作数(文件或目录)。然后您无法使用,-R因为没有操作数,该选项会使grep进程成为当前目录,而不是 stdin。

旁注:-R未由 POSIX 指定,因此不可移植。


我认为groups可能会产生以下形式的输出

username : group1 group2 …

尤其是如果您指定用户名 ( groups username)。如果是这样,您可能需要先删除所有多余的内容。由于不能出现在其他任何地方(它不是用户/组名中的有效字符),因此无论是否生成以 开头的输出,:以下命令都应该有效:groupsusername :

groups username | sed 's/.*: //' | grep -E '(^| )groupname( |$)'

相关内容