2014-01-22 39 views
1

我必須包含如下表示數字的字符串:匹配,可能有一個換行符在任何地方它在一個字符串 - 慶典

\S2=number_goes_here\ 

數量可能會從0.00000和任何東西。但是,在該字符串中的任何位置都可能有換行符,並且我不完全相信如何去匹配該字符串。最終,我只是想從這個數字。重要的是,這個字符串是一片大塊文本,可以由這個樣本(S2的最後一行找到的話)表示:

1.454187\H,0,0.719618,3.525801,1.633708\H,0,-0.454651,2.80328,2.23844\ 
Ru,0,0.025774,1.557599,-0.253913\\Version=EM64L-G09RevD.01\State=6-A\H 
F=-1238.5377983\S2=8.75446\S2-1=0.\S2A=8.750006\RMSD=2.314e-09\Dipole= 

我接受的bash,sed的,awk的,笨拙的人;無論你有什麼想法來解決這個問題。

編輯:

這裏是例子,第一個答案下面似乎並沒有在這個例子中已經工作正常。它只打印「2」。

.631441,-2.132979\H,0,0.20151,-1.464802,-2.95553\H,0,0.377883,-2.50668 
5,-1.874761\\Version=EM64L-G09RevD.01\State=3-A\HF=-1265.9035096\S2=2. 
053325\S2-1=0.\S2A=2.000966\RMSD=1.590e-04\Dipole=0.7197616,-2.1253769 

回答

5
grep -Po '(?<=S2=)[\d.]+' <(tr -d '\n' < file) 

給出

8.75446 
+3

1; OSX用戶(其中​​'grep'不支持'-P' - 因此沒有支持lookarounds - 並且'\ d'不能在集合中使用):'egrep -o'\\ S2 = [0-9 。] +'<(tr -d'\ n' mklement0

+0

@ mklement0我在「S2 = 2。\ n」之後用一個換行符在字符串上試了一下,這不起作用,它只在新行之前拉出來。 –

+0

我在這裏嘗試了實際的答案,它不能正常工作,它可能不是一個真正的新行字符?我編輯了我的問題以提供另一個例子。 –

2

您可以使用,讀啜食狀態的總體文件,刪除換行符,並使用正則表達式搜索一下:

perl -0777 -nE ' 
    $_ = join q||, split /\n/; 
    printf qq|%s\n|, $1 if m/\\S2=([\d.]+)/ 
' infile 

它產生:

8.75446 
0

也可以使用bash,儘管這對於非常大的文件來說效果不好。

#!/bin/bash 
IFS=$'\n' 
string=$(<"test.txt") 
var=$(echo $string) # word-splitting will replace each newline with a space here 

while IFS= read -r word; do 
    [[ $word =~ '\S2='([0-9]*\.[0-9]*)'\' ]] && echo ${BASH_REMATCH[1]} 
done <<< "$var" 

例如,

> ./abovescript 
8.75446 
+0

拋開效率問題,您可以簡化以下方法:'IFS = read -d''-r fileContents <「test.txt」; [[$ fileContents =〜'\ S2 ='([0-9] * \。[0-9] *)]] && echo「$ {BASH_REMATCH [1]}」'。這將整個文件讀入變量'$ fileContents'中,然後匹配它。 另外請注意,然而,OP表示換行符可以是*任意位置*,所以更安全的方法是在匹配之前真正去除*所有換行符。 – mklement0

0

下面是一個gnu awk版本(由於RS與多個字符):

awk -F'\' 'NR==2 {print $1}' RS="S2=" file 
8.75446 

,與工作的版本最awk

awk -F\\ '{for (i=1;i<=NF;i++) if ($i~/S2=/) {split($i,a,"=");print a[2]}}' file 
8.75446 
相關問題