2016-01-30 30 views
2

這似乎很簡單,但我遇到了麻煩。grep整個單詞由大寫字母組成

我有一個文本文件,看起來,例如,像這樣:

這是一個
文本文檔與
一些大寫單詞
但不是所有的人都
全部大寫
iPhone

我想解析的是在文件和匹配全字僅由大寫字母,就像這樣:

文本文檔
一些
BUT NOT
全部大寫

我寫了這個:

grep -o "\w[[:upper:]]\w" Untitled.txt 

這變得非常接近,但是,唉,返回這個:

TEX
DOC
UME
SOM


ALL
CAP
IPH

...這,坦率,我不明白。

所以:我可能會錯過什麼? egrep在OS X下不能很好地工作,因爲我受FreeBSD的grep(grep(BSD grep)2.5.1-FreeBSD)的限制,我猜,我發現了很多針對egrep的解決方案,好像他們會工作不按預期工作。

+1

你或許意味着'\ B',而不是'\ w'? – Biffen

+0

根據你接受的答案,似乎在你自己的line_上輸出每個全大寫單詞_就是你想要的,而不像你期望的樣本輸出所表明的那樣;也許你可以相應地修改你的預期樣本輸出(有一個解釋性說明,因爲至少有一位受訪者試圖解決原始樣本輸出提出的不同問題)。 – mklement0

回答

5

你錯過了*\w是任何字的字符。正確的regexp是:

\<[[:upper:]][[:upper:]]*\> 

\<\>匹配字邊界

+0

謝謝,我會在幾分鐘內將你的答案標記爲答案。 – celestialroad

1

示例輸出顯示的多個空間分離在同一行上大寫單詞,其可與

$ grep -ow '[[:upper:]][[:upper:][:space:]]*[[:upper:]]' infile 
TEXT DOCUMENT 
SOME 
BUT NOT 
ALL CAPS 

任何起始序列和來實現以大寫字符結尾,大寫字符或空白字符之間。 -o僅返回匹配項,-w確保我們不匹配WORDlowercase之類的內容。

+0

'-w'很有幫助,但請注意,包含'[:space:]'沒有任何意義,因爲根據定義,單詞中沒有空格。雖然你的命令仍然按照_GNU_' grep'的意圖工作,但它使用OP所使用的_BSD_「grep」不會_not_。 – mklement0

+0

@ mklement0所以它仍然只返回單個單詞?我查看了BSD grep手冊頁中的'-w'選項,並認爲「好像被'[[:<:]]'和'[[:::]]''包圍」會返回多個單詞...顯然不。 –

+0

我知道你在試圖在單行上返回多個連續的大寫單詞,就像在OP的示例輸出中一樣。 但我懷疑這並不是他們真正想要的,但是,根據他們接受的答案:似乎在自己的行上輸出每個大寫單詞就足夠了。 BSD Grep在你的案例中實際做了什麼只是匹配由大寫字母組成的行_solely_,不要問我爲什麼。 另請注意,即使使用GNU Grep,您的命令也會變得古怪:如果行的最後一個單詞是全大寫單詞,則還會捕獲尾隨空白。 – mklement0

0

你可以使用這個命令:

grep -o -E "\<[[:upper:]]+\>" Untitled.txt 
  • -E激活擴展的正則表達式,這使得+可用其放置1次或多次重複
  • \<\>是錨標記的開始和一個結束字
  • 整個裝置的正則表達式中的一個或多個大寫字符的序列組成全詞

你原來的正則表達式給你三個字母的比賽,因爲\w代表[_[:alnum:]],所以你指示的grep匹配的東西它由三個大字:

  • 第一和第三從[_[:alnum:]]
  • 第二從[[:上:]]範圍
3

爲了補充Zbynek Vyskovsky - kvr000's helpful answer

grep-E選項允許使用的擴展正則表達式,其包括量詞+意指一個或多個,這簡化了解決方案:

grep -Eo '\<[[:upper:]]+\>' Untitled.txt 

此外,如在Benjamin W.'s answer提到的,-w可以使用匹配單詞邊界,而無需將其指定爲正則表達式的一部分:然而

grep -Ewo '[[:upper:]]+' Untitled.txt 

注意的是,-w非標準選項(但雙方BSD/OSX和GNU grep實現它)。


至於egrep:它無非是grep -E一個(有效)的別名,也如所述,激活支持擴展正則表達式更多,但特徵的確切集合是平臺相關

此外,只有GNU grep支持-P選項來支持PCRE(Perl兼容的正則表達式),它提供了更多的功能和靈活性。

+0

謝謝你。有趣的是,你答案中的第一條命令明顯比第二條命令快。 (我使用的實際文本文檔很長。) – celestialroad

+0

@celestialroad:那的確是好奇,感謝您的反饋意見;無關:我添加了關於'egrep'的註釋。 – mklement0

0

的「老派」 RE將更少的字符:

grep -o '[A-Z][A-Z]*' Untitled.txt

它使用-o選項只打印匹配的單詞和反對大寫字母A到Z匹配

添加-w搜索詞和-E調用擴展正則表達式允許這一個是更短:

grep -woE '[A-Z]+\>' Untitled.txt

+0

這將僅限於ASCII字母,因此只能在明確要排除外來字母的情況下使用。 – mklement0

相關問題