2010-04-24 92 views
2

我試圖從使用bash運行的負載中獲取動態信息。我已經得到了一個我想要的字符串,現在我想從中提取可能會有所不同的某些信息。獲取返回該字符串如下:如何從字符串中提取信息

Records: 2910 Deleted: 0 Skipped: 0 Warnings: 0 

每個數量的可以並且將在長度上變化,但整體結構將保持不變。我想要做的是能得到這些數據,並將它們加載到一些bash的變量,即:

RECORDS=?? 
DELETED=?? 
SKIPPED=?? 
WARNING=?? 

在正則表達式,我會做這樣的:

Records: (\d*?) Deleted: (\d*?) Skipped (\d*?) Warnings (\d*?) 

,並使用4組我的變數。

+0

http://stackoverflow.com/questions/918886/split-string-on-delimiter-in-bash – 2010-04-24 23:42:54

+0

該問題指的是基於分隔符分割字符串,我只是萬噸拉數字,我沒有共同的分隔符。 – 2010-04-25 00:01:30

+1

實際上,項目之間的空間看起來像是一個合適的分隔符。在答案中查看腳本的剪切版本。 – rmarimon 2010-04-25 00:15:24

回答

4

可以在猛砸版本> = 3.2使用正則表達式匹配:

[[ $line =~ ([[:digit:]]+).*([[:digit:]]+).*([[:digit:]]+).*([[:digit:]]+) ]] 

RECORDS=${BASH_REMATCH[1]} 
DELETED=${BASH_REMATCH[2]} 
SKIPPED=${BASH_REMATCH[3]} 
WARNING=${BASH_REMATCH[4]} 
+0

很棒的回答。即使我寫了另一個答案,我會選擇你。這是我不知道的bash的一些功能。 – rmarimon 2010-04-25 03:02:53

+0

@rmarimon,這個工作,但只有當你的線是每次顯示的完全一樣。如果有更多的數據,它將無法工作。 – ghostdog74 2010-04-25 03:17:09

3

內置read命令就可以了:

read TMP1 RECORDS TMP2 DELETED TMP3 SKIPPED TMP4 WARNING 

更新:您還可以使用set

set $line 
RECORDS=$2 
DELETED=$4 
SKIPPED=$6 
WARNING=$8 
+0

閱讀是爲了捕捉用戶輸入,即時通訊沒有手動輸入,該字符串設置爲一個名爲'$ r'的變量。 – 2010-04-25 00:04:47

+0

@Russ這裏是一個更新的答案,也適用於字符串。 – Bolo 2010-04-25 00:21:28

+2

@Russ:'read'可以從標準輸入獲取值:'s =「foo bar baz」;閱讀b c <<< $ s' – 2010-04-25 00:23:17

0

你可以嘗試用 'sed的' 或 '一刀切' 的東西取決於像這樣的線的結構:

#!/bin/sh                  

DYNAMIC="Records: 2910 Deleted: 1 Skipped: 2 Warnings: 3" 

RECORDS=`echo "$DYNAMIC" | sed 's/.*Records: \([0-9]*\).*/\1/g'` 
DELETED=`echo "$DYNAMIC" | sed 's/.*Deleted: \([0-9]*\).*/\1/g'` 
SKIPPED=`echo "$DYNAMIC" | sed 's/.*Skipped: \([0-9]*\).*/\1/g'` 
WARNINGS=`echo "$DYNAMIC" | sed 's/.*Warnings: \([0-9]*\).*/\1/g'` 

echo "Records $RECORDS" 
echo "Deleted $DELETED" 
echo "Skipped $SKIPPED" 
echo "Warnings $WARNINGS" 

echo "$DYNAMIC" | cut -d " " -f2 
echo "$DYNAMIC" | cut -d " " -f4 
echo "$DYNAMIC" | cut -d " " -f6 
echo "$DYNAMIC" | cut -d " " -f8 
+0

太複雜了,我更喜歡Bolo的解決方案。 – 2010-04-25 05:28:21

1

這裏是你可以使用只產生了一些名稱/值對的外殼功能。它假定如你所說的事情被格式化,但很容易改變:

parseline() { 
    while [ $# -ge 2 ] ; do 
     eval $(echo $1 | tr -d : | tr '[a-z]' '[A-Z]')="$2" 
     shift 2 
    done 
} 

執行它想:

$ parseline Records: 2910 Deleted: 0 Skipped: 0 Warnings: 0 
$ echo $RECORDS 
2910 
$ echo $WARNINGS 
0 
0
#!/bin/bash 
s="Records: 2910 Deleted: 0 Skipped: 0 Warnings: 0" 
s=${s//: /=} 
for i in $(printf ${s// /"\n"}) 
do 
eval $i 
done 

echo "Records: $Records" 
echo "Deleted: $Deleted" 
echo "Skipped: $Skipped" 
echo "Warnings: $Warnings" 

輸出

$ ./shell.sh 
Records: 2910 
Deleted: 0 
Skipped: 0 
Warnings: 0