2016-07-09 24 views
1

我試圖做一些SED瘋狂的正則表達式,但我不允許在使用擴展正則表達式的sed

我只是沒有得到正則表達式或不同的正則表達式在sed

文件我「米,工作就像是

46,uie,ieo 
39,ieu,tii 
44-46,yut,til 
45,dkd,ytu 
65,dkd,ytu 
40-45,dkd,ytu 

當我做

cat text.txt | sed s/^4[0-9],//g 

我幾乎得到了我想要的東西,我得到

uie,ieo 
39,ieu,tii 
44-46,yut,til 
dkd,ytu 
65,dkd,ytu 
40-45,dkd,ytu 

但我想擺脫一個人的的是類似40-45和44-46 所以我已經試過

cat text.txt | sed s/^4[0-9](-4[0-9])?,//g 
-bash: syntax error near unexpected token `(' 

當我嘗試

cat text.txt | sed s/^4[0-9]-?4?[0-9]?,//g 

我只是得到

46,uie,ieo 
39,ieu,tii 
44-46,yut,til 
45,dkd,ytu 
65,dkd,ytu 
40-45,dkd,ytu 

所以沒有被過濾

謝謝你!

+0

用反斜槓將括號括起來,如下所示:'cat test | sed -r s/^ 4 [0-9] \( - 4 [0-9] \)?,// g'。 – 1sloc

+0

它是3列csv文件,你想刪除第一列,使用'cut' –

+0

@CasimiretHippolyte:他顯然不想刪除第一列,除非它在40至49範圍內。 –

回答

4
cat text.txt | sed s/^4[0-9](-4[0-9])?,//g 

兩個問題。

首先,您需要引用sed的參數。它包含由shell識別的元字符,如(?;你需要引用這個參數,所以shell將它視爲一個字符串,而不會試圖解釋它。

cat text.txt | sed 's/^4[0-9](-4[0-9])?,//g' # this still doesn't work 

其次,sed默認情況下不使用擴展正則表達式。如果你使用GNU的sed(類型sed --version證實了這一點),你可以使用-E選項來啓用擴展正則表達式:

cat text.txt | sed -E 's/^4[0-9](-4[0-9])?,//g' 

,或者你可以使用反斜槓讓sed識別()?字符:

cat text.txt | sed 's/^4[0-9]\(-4[0-9]\)\?,//g' 

最後,這是一個Useless Use of catsed完全能夠從標準輸入或指定文件讀取輸入;你並不需要通過管道從cat給它的輸入:

sed 's/^4[0-9]\(-4[0-9]\)\?,//g' text.txt 

-E選項是POSIX規定;我認爲這是一個相對較新的增加。自2006年以來,GNU sed支持-E(最初與BSD sed兼容),但目前沒有在任何發佈版本中記錄。文檔在2013年被添加,但是最近的官方發佈的GNU sed在2012年是4.2.2。

+2

'-E'而不是'-r'更便攜。 – sjsam

+0

@sjsam:已更新。 –

+0

這很快;) – sjsam

0

您可以使用awk

awk -F, '!/^4[0-9]\>/;{print $2,$3}' text.txt 

細節:

!/^4[0-9]\>/ # returns 1 (true) when the line doesn't start with a number between 
      # 40 and 49 (`\>` figures a boundary) 
      # (when the expression returns true, the whole line is printed and 
      # awk jumps to the next line) 

{print $2,$3} # otherwise fields 2 and 3 are printed 

-F,定義字段分隔符。

0

似乎有幾個基本的UNIX事情你錯了。那些需要引用sed的參數。它們被shell解釋爲文件名稱。此外,這是貓的無關用途,只需使用shell重定向<即可獲得相同的影響(並且效率更高)。另外,在sed正則表達式中,()?是正常字符,除非用\轉義。所以結果是這對我很有用:

sed 's/^4[0-9]\(-4[0-9]\)\?,//g' < text.txt