2017-02-08 19 views
-1

Я очень новичок в сценариях оболочки и должен выполнять столько задач вокруг него. Я стараюсь учиться так быстро, но иногда скрипты оболочки делают задачу очень простой, и в других случаях она просто играет со мной. И сейчас я сталкиваюсь с подобной ситуацией. У меня есть команда, которая дает мне выход вроде этого.Как обрабатывать строку в использовании awk в сценарии оболочки

File     Dependents 
    ---------------------------------------------------------------------------- 
<File> is a requisite of <Dependents> 
Path: /usr/lib/obj 
    Java 1.0.0.0   analysis 0.0.0.2 
         runtime 1.2.0.0 
         client 1.2.0.0 
         framework 6.1.9.100 
         sguide 1.9.10.0 
         sysmgt 6.1.9.100 
         dsm 6.1.9.200 

Path: /etc/obj 
    Java 1.0.0.0   analysis 1.2.0.2 
         runtime 2.0.0.0 
         client3 6.1.9.0 
         sysmgt 6.1.9.0 
         dsm2 6.1.9.0 

Теперь я хочу получить список зависимостей в массив для дальнейшей обработки. Это то, что я могу сделать, до сих пор:

<command> | cut -f1 | grep '[a-z]' | grep -v File | grep -v : | awk '{ print $1}' 

выход:

Java<<< I want this to be analysis 
runtime 
client 
framework 
sguide 
sysmgt 
dsm 

Java<<< want this to be analysis 
runtime 
client3 
sysmgt 
dsm2 

Я должен захватить эти два списка в двух отдельных массивов.

Может кто-то, пожалуйста, помогите мне в достижении этого выхода элегантным способом. Я не хочу забивать этот код с помощью моего метода грубой силы, включающего множество условий и сравнений.

+0

Вы будете лучше читать на awk-массивах и сохранить свою обработку в конечном скрипте awk (в вашем конвейере). Не зная, как будет выглядеть ваша окончательная обработка, сложно комментировать/помогать дальше. Удачи. – shellter

ответ

2

awk на помощь!

$ arr1=$(command ... | awk -v c=1 '!NF{f=0} f && s==c{print $1} /Java/{f=1; s++; if(s==c) print $(NF-1)}') 

$ arr2=$(command ... | awk -v c=2 '!NF{f=0} f && s==c{print $1} /Java/{f=1; s++; if(s==c) print $(NF-1)}') 

$ echo $arr1 
analysis runtime client framework sguide sysmgt dsm 

$ echo $arr2 
analysis runtime client3 sysmgt dsm2 

возможно лучше, если вы выполните команду один раз и разделите результаты на два массива.

Объяснение

awk -v c=1 набор переменную AWK с до 1 (описывает номер группы экземпляра)

'!NF{f=0}, если нет полей (пустая строка) сброса F

f && s==c{print $1} если Р установленный и счетчик равен c печать первого поля

/Java/{f=1; s++;, когда шаблон соответствует Java, задает значение f и счетчик приращений и ...if(s==c) print $(NF-1)}' если встречные совпадения c напечатают предпоследнее поле.

+0

Большое спасибо. Это именно то, что я искал. Не могли бы вы объяснить, '! NF {f = 0} f && s == c {print $ 1}/Java/{f = 1; s ++; if (s == c) print $ (NF-1)} ' Это мастер-ход, но я до сих пор не могу его декодировать. – Albert

+0

Все, что я понял, это то, что print $ (NF-1)} используется для получения поля last-1, а остальные инструкции предназначены для получения начального и конечного условий. Не могли бы вы рассказать. – Albert

1

Вы можете исправить свое решение путем удаления подстроки Java первым:

command | sed 's/Java [^ ]*//' | cut -f1 | grep '[a-z]' | grep -v File | grep -v : | awk '{ print $1}' 

При использовании awk, вы можете лучше использовать полную силу awk. Просто сказать, что вы хотите, чтобы распечатать вторую последнее поле в любой строке с номером:

command | awk '/[0-9]/ { print $(NF-1) }' 

Это лучше, чем пытаться использовать sed (у вас есть вкладки или пробелы?)

command | sed -n '/[0-9].[0-9]/ s/^.* \([^ ]*\) .*/\1/p' 

Забавная решение использует rev, чтобы вернуть текст. Таким образом, cut может найти второе поле.

command | grep '[0-9].[0-9]' | rev | cut -d " " -f2 | rev 

Для людей, которые только читают последнюю строку, я буду повторять awk решение:

command | awk '/[0-9]/ { print $(NF-1) }' 
+0

Большое спасибо за предоставление множества замечательных способов. Но вышеупомянутый мне подходит лучше, поэтому я принимаю это – Albert

Смежные вопросы