2014-02-05 75 views
0

我試圖獲得以「ab」開頭或以「1」結尾的用戶。只有用戶。以下命令適用於誰,但出於某種原因而不適用於用戶。Linux批處理命令獲取從特定字符串開始的用戶

users | grep -e "^ab" -e "1$" 

,結果是我得到的系統

+1

如果有一個以上的用戶,在' users'命令將它們列在一行(至少它每行列出多個用戶;我沒有嘗試過很多很多很多的登錄),而'who'每行列出一個用戶。我懷疑你的正則表達式是否足夠敏感以正確處理這個問題('who','1 $'將與時間字段匹配,除非你包含了你沒有顯示的過濾器)。 –

+0

爲什麼不在'/ etc/passwd'上使用'awk'? –

+0

@BasileStarynkevitch如果您在* all *用戶中查看,則無論用戶是否登錄,這都是一種選擇。儘管OP的措辭沒有明確說明,但他/她對「用戶」(和「who」)的選擇意味着它是關於用戶登錄的。 @blended:正確嗎? – mklement0

回答

4

users的所有用戶輸出登錄在行用戶。如果要與grep分別匹配它們,從users成各個行第一分割輸出,通過用一個新行替換每個空間:

users | tr ' ' '\n' | grep -e "^ab" -e "1$" 

更新:可替代地,可以跳過tr步驟如果你使用grep的-o選項(輸出所有匹配而不僅僅是線),並使用\b到邊界匹配字(與+取代*如果「AB」和「1」由本身應不匹配):

users | grep -o -e '\bab\w*' -e '\b\w*1' 

OSX用戶:莫名其妙地,上述有時跳過匹配 - 10.9上與輸入字符串"ab 1 abc x1"觀察到您可以解決此通過正則表達式組合成一個單一的一個,並使用egrepgrep -E

users | egrep -o '\b(ab\w*|\w*1)' 

1

users輸出一起運行,在一行。

who的輸出是分割的,每行一個,其他細節如下。

您對^$的使用只能匹配一行的開頭或結尾。

who | grep -e '^ab' -e '1$' 

......說來匹配用戶名稱開頭「AB」或者其終端從他們登錄(或其他一些領域,這取決於你的who版本,可能時間)與1結束,因爲登錄終端是who中的最後一個字段。

who只匹配用戶名,您可以cut的輸出連接到空間領域,並採取第一場:

who | cut -d ' ' -f 1 | grep -e '^ab' -e '1$' 

要匹配的users輸出,您不能使用開始和行的結束標記^…$,但你可以\b

users | grep -e '\bab' -e '1\b' 

測試「單詞邊界」如果你想在一個序列中提取匹配的名字:

users | grep -o -e '\bab\w*\b' -e '\b\w*1\b' 

如果您需要提取用戶列表(空間拆分)並測試每個用戶列表,執行某些操作,您可以使用read

users | while read -d ' ' user 
    do 
     if echo $user | grep -q -e '^ab' -e '1$' 
     then 
      echo "you have a nice name" | write $user 
     fi 
    done 

由於@mklement在評論中指出,BASH有自己內置的正則表達式匹配,以及:

users | while read -d ' ' user 
    do 
     if [[ $user =~ '^ab|1$' ]] 
     then 
      echo "this is a little nicer way to match, $user" | write $user 
     fi 
    done 
+0

+1這個全面的答案,但你的'grep'解決方案與'\ b'需要一些愛:'-o'缺少僅輸出匹配的子字符串,並且必須修改「-e」正則表達式以僅匹配單個標記;狡辯:並非所有版本的who都列出了終端(例如OSX 10.9和Ubuntu 12.04)。 – mklement0

+0

沒有想到這是一個目標('-o'),但補充說,並且奇怪的是,Ubuntu不同於Fedora;我對達爾文做的事情不同,在那裏完全不同的祖先並不感到驚訝。 (儘管OP確實指定了Linux)。增加了你的建議 – BRFennPocock

+0

感謝您的更新;爲了使'-o'變體輸出實際的用戶名,而不僅僅是匹配的前綴/後綴,你需要'-e'\ bab \ w *'-e'\ b \ w * 1''。 – mklement0

相關問題