簡體   English   中英

使用Shell腳本從字符串中提取信息

[英]Extracting information from string using shell script

我有一個文本文件,其行格式如下:

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

主要問題是信息以不同的順序出現,有些信息每行中包含更多/更少的不需要的數據。 因此,拆分為一個數組不會削減它。

解析復雜行的一種通用方法是使用正則表達式來描述它們,然后使用括號指出哪些部分是有趣的:

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

要將其讀入單獨的shell變量,請使用以下模式:

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

Perl正則表達式的grep示例:

#!/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 "(?<=@str:)[^|]*")"        # @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

這是一個簡單的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

暫無
暫無

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

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