如何使用 grep 列出不以“c”开头的项目

如何使用 grep 列出不以“c”开头的项目

在我的一门计算机科学课上,我的老师给了我们一个用户文件:users.txt.该文件的行如下所示:

$ head users.txt

root:x:0:0:root:/root:/bin/bash
apache:x:71:71:system user for apache2:/var/www:/bin/sh
ftp:x:73:73:system user for proftpd:/var/ftp:/bin/false
c0407115:x:1501:1000:Alberto Damiao Canelas Fraga:/home/c0407115:/bin/bash
c0407165:x:1502:1000:Alexandre Viriato Morais Magalhaes:/home/c0407165:/bin/bash
c0407110:x:1503:1000:Alvaro Manuel Figueiredo Nunes de Sousa:/home/c0407110:/bin/bash
c0307009:x:1504:1000:Ana Marta Tavares Laranjeira:/home/c0307009:/bin/bash
c0416079:x:1505:1000:Ana Rita Caetano Mourato:/home/c0416079:/bin/bash
c0407137:x:1506:1000:André Brito Coimbra:/home/c0407137:/bin/bash
c0307068:x:1507:1000:André Filipe Rios da Fonseca Alves Modesto:/home/c0307068:/bin/bash

然后老师要求做以下事情:

编写一个命令,列出所有非学生用户(也就是说,他们的登录名不是以 c 开头的??)

我的第一个方法如下:

$ cat users.txt | grep [^c]*

grep: figures: Is a directory
grep: practice: Is a directory

我收到与我正在处理的目录中的某些目录相关的错误消息。这些是我的目录中的当前文件:

$ ls

archive  figures  practice  users.txt

然后我尝试做相反的事情:使用反向匹配选项:

$ cat users.txt | grep -v [c]*
$

但这次我没有任何输出。为什么这不起作用,为什么我收到该错误消息,以及如何做到这一点?谢谢

答案1

... | grep [^c]*

这里,[^c]*是一个 glob,一个文件名模式,类似于 例如*.txt

[^c]含义与正则表达式中的含义相同,即它匹配不是 的任何单个字符c。与正则表达式不同,*匹配全局中任意数量的任意字符。因此,整个内容匹配并扩展到任何不以 开头的文件名c,例如所有archive figures practice users.txt.

当给定参数列表时,不带-e-f选项,grep将第一个参数作为模式,因此该命令将archive在其余文件中查找该字符串。grep默认情况下不处理目录,因此您会收到这些错误。

grep如果该模式包含 shell 特有的字符,则需要引用该模式以使其保持不变。或者为了安全起见,如果有任何特殊字符,请引用该模式。


作为正则表达式,[^c]*将匹配任意数量的不是 的连续字符c。但由于这包括零长度匹配,grep '[^c]*'因此将匹配任何行。

您需要将模式锁定到行的开头,并使其至少需要一个字符。

由于这是一项作业,请尝试这些命令,看看您是否可以找出它们为什么这样做:

grep        c   users.txt
grep -v     c   users.txt
grep       ^c   users.txt
grep -v    ^c   users.txt
grep    '^[^c]' users.txt
grep -v '^[^c]' users.txt

[c]与 just 相同c,所以我将省略那个。它本身^对于 shell 来说实际上并不特殊,所以不需要在这里引用。那里的一些模式可能与其他一些模式等效。)

答案2

您使用了错误的正则表达式。这是正确的:

cat ./users.txt | grep -v '^c'

您也可以在不使用的情况下执行此操作cat

grep -v '^c' ./users.txt

相关内容