簡體   English   中英

grep的正則表達式問題

[英]Regex issue with grep

我試圖寫一個正則表達式,它將在CVS(Coma分隔值)文件中找到一堆電話號碼。

Catch是我只對特定列中的電話號碼感興趣(僅在特定數量的昏迷之后才感興趣)。 在下面,我有正則表達式可以做到這一點,並且每個Javascript標准都可以正常工作。

(?:^([^^]*\,){3}[^^]*)\d{3}-\d{3}-\d{4}

我實際上在Bash中工作,並且使用sed,grep,但我什至找不到grep和sed使用的正則表達式標准?

這是示例文本。

請注意,現在我使用'^'代替','來使值分開,因為用戶在值中包括了逗號。

這不是實際數據,只是為了保留人們的隱私而做的准備

28434658^17 Three^2013-09-19T19:57:23Z^80 W 54th St, Penthouse & 4th Fl, NY, 10018s212-409-1641^^Mary Szyb 347-340-1918^2 x week Thur 2.5hrs  & Sat 4 hrs
28937693^356 West 36th street^2013-09-19T18:17:57Z^356 West 36th street, suite 706sNew York New York 10018^null^null^on call: 
29219313^333 rector pl^2013-10-07T17:11:36Z^333 Rector Place 248-469-5859^^Jose Hernandez^2 x week Wed & Fri
28854346^50 Can^2013-09-23T13:10:54Z^152 East 28th Street, 7th Floor, NY, 10018s917-932-3962s646-710-4170^155 W 24rd St 3rd FL^null^Swlvia Smith347-933-6630sIrena Brown 347-991-1346s5 x week Mon-Fri
28434698^4Eleven^2013-09-19T19:57:23Z^112 West 28th Street, 3th Fl,sNY, 10018s917-922-3862s646-710-4170^^null^null

我還要澄清一件事,正確的輸出將是:

212-409-1641
248-469-5859
917-932-3962
646-710-4170
917-922-3862
646-710-4170

因為這些是第4列中唯一的電話號碼

以下應為您工作。

grep -Po '(\d{3}-){2}\d{4}' file.csv

更新:

按照實際數據中的逗號替換^后。

28434658,17 Three,2013-09-19T19:57:23Z,80 W 54th St, Penthouse & 4th Fl, NY, 10018s212-409-1641,Mary Szyb 347-340-1918,2 x week Thur 2.5hrs  & Sat 4 hrs
28937693,356 West 36th street,2013-09-19T18:17:57Z,356 West 36th street, suite 706sNew York New York 10018,null,null,on call: 
29219313,333 rector pl,2013-10-07T17:11:36Z,333 Rector Place 248-469-5859,Jose Hernandez,2 x week Wed & Fri
28854346,50 Can,2013-09-23T13:10:54Z,152 East 28th Street, 7th Floor, NY, 10018s917-932-3962s646-710-4170,155 W24rd St 3rd FL,null,Swlvia Smith347-933-6630sIrena Brown 347-991-1346s5 x week Mon-Fri
28434698,4Eleven,2013-09-19T19:57:23Z,112 West 28th Street, 3th Fl,sNY, 10018s917-922-3862s646-710-4170,null,null

您可以嘗試以下方法。

perl -nle '@F = split(/,(?!s| )/, $_); print $1 while ($F[3] =~ /((\d{3}-){2}\d{4})/g)' file.csv

產量

212-409-1641
248-469-5859
917-932-3962
646-710-4170
917-922-3862
646-710-4170

Grep可以將perl或posix標准與-P或-E一起使用。 有關詳細信息,請參見man grep 對於這樣的事情,我通常首先使用cut來分隔字段,並假設沒有任何字段將包含列定界符。

echo "a,b,c,123-555-1212,d,e,f" | cut -f 4 -d','

或來自文件

while read line; do
   c4=$(echo $line | cut -f 4 -d',')
done < /tmp/file.csv

如果任何一列都可以包含逗號,那么最好切換到使用ruby,python等的CSV庫。

更新:使用-d'^'分隔列,您可以輕松地將感興趣的列匹配,如上所述,使用sed的棘手部分是提取電話號碼,

f="80 W 54th St, Penthouse & 4th Fl, NY, 10018s212-409-1641"
echo $f | sed -r 's/(.*?)([0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$)/\2/'
212-409-1641

不是必須使用擴展的regex sed命令行參數(-r)似乎不能使用\\ d {3}之類的正則表達式文字。 sed的文檔可在信息頁面中找到,但通常更容易grep net。 這是一個非常不錯的教程: http : //www.thegeekstuff.com/2009/10/unix-sed-tutorial-advanced-sed-substitution-examples/

使用awk的答案:

awk -F'^' '{ 
  start = 0;
  str = substr($4, start);
  while (match(str, /([0-9]{3})-[0-9]{3}-[0-9]{4}/)) {
    print substr(str, RSTART, RLENGTH);
    start = RSTART + RLENGTH;
    str = substr(str, start);
  }
}' datafile

這將占據第4列,重復匹配電話模式,然后將其打印在一行上。

我發布結束工作的正則表達式:

([0-9]{3}-[0-9]{3}-[0-9]{4})(?=[^^]*(\^[^^]*){3}$)

謝謝大家的幫助

我想從這個問題中可以得出的教訓是,如果一個解決方案不起作用,請嘗試從不同角度進行工作,在這種情況下,請從背面數列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM