Как я могу получить информацию из строки - PullRequest
2 голосов
/ 25 апреля 2010

Я пытаюсь извлечь динамику из нагрузки, которую я использую, используя bash. Я дошел до того, что получил нужную строку, теперь из этого я хочу извлечь определенную информацию, которая может варьироваться. Возвращаемая строка выглядит следующим образом:

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

Каждое число может и будет различаться по длине, но общая структура останется прежней. Я хочу получить эти цифры и загрузить их в некоторые переменные bash, например:

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

В регулярном выражении я бы сделал это так:

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

и используйте 4 группы в моих переменных.

Ответы [ 5 ]

4 голосов
/ 25 апреля 2010

Вы можете использовать регулярное выражение в версиях Bash> = 3.2:

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

RECORDS=${BASH_REMATCH[1]}
DELETED=${BASH_REMATCH[2]}
SKIPPED=${BASH_REMATCH[3]}
WARNING=${BASH_REMATCH[4]}
3 голосов
/ 25 апреля 2010

Встроенная команда read поможет:

read TMP1 RECORDS TMP2 DELETED TMP3 SKIPPED TMP4 WARNING

Обновление : Вы также можете использовать set:

set $line
RECORDS=$2
DELETED=$4
SKIPPED=$6
WARNING=$8
1 голос
/ 25 апреля 2010

Вот функция оболочки, которую вы можете использовать, которая просто создает несколько пар имя / значение. Предполагается, что все отформатировано, как вы сказали, но его легко изменить:

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 голосов
/ 25 апреля 2010
#!/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
0 голосов
/ 25 апреля 2010

Вы можете попробовать что-то с «sed» или «cut» в зависимости от структуры линии, например:

#!/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
...