2015-07-02 202 views
1

字符串中提取信息,我有以下格式的行文本文件:使用shell腳本

9999.0  @str:Attribute|ID=foo_1|SendingTime=2015-07-24 05:12:12.123|S-Id=9999|IDSource=Test_3|Qty=1555 

從這個我想從每行獲得各個部分的保持,使用shell腳本。舉例來說:

VAR1 = Attribute, 
VAR2 = Date, 
VAR3 = timeStamp, 
VAR4 = Qty 

主要問題是信息以不同順序排列,一些信息在每行中有更多/更少的不需要的數據。因此分裂到一個數組只是不會削減它。

+4

有沒有'Date'也不'timeStamp'輸入。如果你想得到具體的解決方案,請使用更好的樣本輸入和預期輸出。 – choroba

+0

我認爲日期和時間戳是從'SendingTime'字段中提取的。 – chepner

回答

0

爲例與grepPerl正則表達式:

#!/bin/bash 
s="9999.0  @str:Attribute|ID=foo_1|SendingTime=2015-07-24 05:12:12.123|S-Id=9999|IDSource=Test_3|Qty=1555" 
var1="$(echo "$s" |grep -oP "(?<[email protected]:)[^|]*")"  # @str: 
var2="$(echo "$s" |grep -oP "(?<=SendingTime=)[^|]*")" # SendingTime= 
var3="${var2#* }"          # Date 
var2="${var2% *}"          # timestamp 
var4="$(echo "$s" |grep -oP "(?<=Qty=)[^|]*")"   # Qty 
echo "$var1 | $var2 | $var3 | $var4" 

輸出:

Attribute | 2015-07-24 | 05:12:12.123 | 1555 
+1

很多很棒的幫助!這是我最終使用的版本,謝謝<3 – Murrmel5

0

的一般方法來分析複雜的線條是使用正則表達式來形容他們,然後用括號譜寫哪些部分是有趣:

s='9999.0  @str:Attribute|ID=foo_1|SendingTime=2015-07-24 05:12:12.123|S-Id=9999|IDSource=Test_3|Qty=1555' 
pattern='.*@str:\([^|]*\).*ID=\([^|]*\).*SendingTime=\([^|]*\).*Qty=\([^|]*\).*$' 
extract_interesting() { 
    input=$1 
    pattern=$2 
    echo "$input" | sed s/"$pattern"/'\1#\2#\3#\4'/ 
} 

功能extract_interesting()將打印線的四個有趣的部分,通過#符號分隔:

extract_interesting "$s" "$pattern" 

將打印

Attribute#foo_1#2015-07-24 05:12:12.123#1555 

要閱讀此成單獨的殼變量,使用這種模式:

IFS=# read a b c d < <(extract_interesting "$s" "$pattern") 

然後

echo "$a"; echo "$b"; echo "$c"; echo "$d" 

將打印

Attribute 
foo_1 
2015-07-24 05:12:12.123 
1555 
+1

我會用'bash'正則表達式匹配替換'sed'。 '[[$ input =〜$ pattern]]',然後從'BASH_REMATCH'中提取4個值。 – chepner

+0

你說得對。相同的方法,不同的手段。我在這裏使用'sed'有點古老。 – Alfe

+2

在每條生產線上分岔一個新流程都會產生很大的開銷。 – chepner

0

下面是一個簡單的awk腳本其中挑選出的領域,並將它們打印在指定的順序。

awk -F '\t' 'BEGIN { f = split("Attribute|Date|timeStamp|Qty", k, /\|/) } 
    { n = split($2, a, /\|/); for (i=1; i<=n; ++i) { 
     if (a[i] ~ /^@str:/) v["Attribute"] = substr(a[i], 6); 
     else if (a[i] ~ /^SendingTime=/) { 
      v["Date"] = substr(a[i], 13, 10); v["timeStamp"] = substr(a[i], 24) 
     } else if (a[i] ~ /^Qty=/) v["Qty"] = substr(a[i], 5); 
    } 
    for (s=1; s<=f; s++) printf("%s=%s\n", k[s], v[k[s]]); 
    delete v }' inputfile 

BEGIN塊設置,我們要收集並打印,在我們希望的順序領域的標籤組成的數組k。最後的for循環遍歷這個數組。主要的複雜性是在中間塊,我們進一步拆分|分隔符上的第二個字段並遍歷結果;我們想要提取的每個字段都根據匹配中的偏移量進行填充。

對沒有檢查的字段沒有檢查,還有一些關於輸入(製表符分隔,是?)和輸出格式的假設,因爲你的問題不是很清楚。

在線演示:http://ideone.com/2yvz2X