CentOS 5.x
Я пытаюсь создать сценарий оболочки, который ищет данные, предоставленные через стандартный ввод. Вот пример входящего потока:
Date: 1/1/11
Time: 12:00 AM
Foo: 12345
Foo1: dskjflsdkjflksdjlfds
Foo2: 123456789
Foo3: kdsjflskdjflkjsdlkfjsdlkjflksdjflkjsdklfjlksdjflk
Эта информация не существует в файле, она будет отправлена скрипту только в режиме реального времени как стандартный вывод из другого приложения.
Я хочу, чтобы сценарий просматривал данные и анализировал значения для Фу: и Foo2: сохраняя их как переменные для использования позже в скрипте.
Моя попытка пересмотренного сценария такова:
#!/bin/bash
while read data; do
SearchCriteria1=$(echo "$data" | grep "Foo: " | cut -c 5-)
SearchCriteria2=$(echo "$data" | grep "Foo2: " | cut -c 6-)
echo $SearchCriteria1 >> test.1
echo $SearchCriteria2 >> test.2
done
Готовый сценарий фактически не будет использовать файлы test.1 или test 2. Я просто перечислил их здесь для более простых примеров.
В этом примере я ожидал бы, что test.1 будет иметь:
12345
В этом примере я ожидал, что test.2 будет иметь:
123456789
Однако, когда я тестирую это, оба теста test.1 и test.2 пусты, и я знаю, что в данных есть действительная информация.
Я упускаю кое-что очевидное. Может кто-нибудь уточнить?
Подумайте, откуда ваши greps получают данные. Вы не указали им имя входного файла, поэтому они читают со стандартного ввода. Каков их стандартный ввод? Для него нет перенаправления, и нет канала, идущего в greps, поэтому они работают с унаследованным стандартным вводом цикла.
В read
выполняется только один раз. Он читает первую строку в $data
, который вы никогда нигде не используете (это должно быть признаком того, что что-то не так). Затем запускается первый grep, он потребляет весь ввод, а второй grep прикрепляется к тому же вводу, поэтому он немедленно получает EOF.
Вероятно, это ближе к тому, что вы хотели:
SearchCriteria1=$(echo "$data" | grep "Foo " | cut -c 10-)
SearchCriteria2=$(echo "$data" | grep "Foo2 " | cut -c 13-)
Точки с запятой в конце были бесполезны, поэтому я снял их.
Также вы, вероятно, захотите добавить в test.1
и test.2
в противном случае каждая итерация цикла перезаписывает то, что написала предыдущая.
Глядя на общую картину, кажется, что вам нужен «многопользовательский grep». Ваш цикл чтения с индивидуальными командами greps для каждой строки - это один из способов его реализации, но не очень эффективный. Некоторые другие способы недавно обсуждались на https://stackoverflow.com/questions/11676350/grepping-a-20g-file-in-bash/11676853
input stream producer |
egrep 'Foo:|Foo2:' |
while read foo data
do
case $foo in
Foo:) echo "do something with $foo -- $data" ;;
Foo2:) echo "do something else with $foo -- $data" ;;
esac
done
В egrep Строка не является строго необходимой, но исключает ненужный ввод для цикла. затем читать на две переменные (фу и данные) и используйте кейс выбирать между ними и действовать соответственно (на этом этапе вы можете назначить данные в другую переменную, если хотите).
Как насчет этого:
$ ./another.app | awk '/Foo: / { print $2 }' > test.1
$ ./another.app | awk '/Foo2: / { print $2 }' > test.2