Grep

如何使用 grep 列出不以“c”開頭的項目

  • November 3, 2022

在我的一堂電腦科學課上,我的老師給了我們一個使用者文件: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]*
$

但這次我沒有輸出。為什麼這不起作用,為什麼我收到該錯誤消息,以及如何做到這一點?謝謝

... | grep [^c]*

這裡,[^c]*是一個 glob,一個文件名模式,類似於 eg *.txt

[^c]意味著與正則表達式中的相同,即它匹配任何不是 a 的單個字元c。與正則表達式不同,*匹配 glob 中任意數量的任意字元。因此,整個內容匹配並擴展到任何不以 a 開頭的文件名c,例如所有archive figures practice users.txt.

當給定參數列表時,沒有-eor-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 所特有的,所以這裡不需要引用。那裡的一些模式可能與其他模式等價。)

引用自:https://unix.stackexchange.com/questions/723568