2014-09-03 2 views
0

Моего файл выглядит следующим образом:UNIX: рекурсивно вставить подстроку в ту же строку в UNIX

$ cat a 
Server1 - free space:/60% : /opt 40%: /var 50%  
Server2 - free space:/50% : /opt 30%: /var 60%  
Server3 - free space:/30% : /opt 50%: /var 40% 

Выход должны быть записан в другой файл б. Мой ожидаемый результат будет выглядеть следующим образом:

$ cat b 
Server1 - free space:/60% 
Server1 - free space: /opt 40% 
Server1 - free space: /var 50% 
Server2 - free space:/50% 
Server2 - free space: /opt 30% 
Server2 - free space: /var 60% 
Server3 - free space:/30% 
Server3 - free space: /opt 50% 
Server3 - free space: /var 40% 

ответ

4
$ awk -F' *: *' -v OFS=': ' '{for (i=2;i<=NF;i++) print $1, $i}' file 
Server1 - free space:/60% 
Server1 - free space: /opt 40% 
Server1 - free space: /var 50% 
Server2 - free space:/50% 
Server2 - free space: /opt 30% 
Server2 - free space: /var 60% 
Server3 - free space:/30% 
Server3 - free space: /opt 50% 
Server3 - free space: /var 40% 
1

В этом случае вам нужно отделить «субъект» текст из ваших данных.

С awk вы получаете это бесплатно, так как он анализирует каждую строку ввода и помещает каждое поле в пронумерованные переменные - $ 1, $ 2 и т. Д. Вы также получаете фактическое количество полей - NF - для каждой строки бесплатно , рассчитываемый AWK

Учитывая это, вы можете начать с

awk '{ print $1, $2 }' a 

Output: Server1 - 

Не полностью, что вы хотите.

Вы могли держать подсчет вручную, или даже просто жесткий код некоторые из текста:

awk '{ Subject=$1" "$2" "$3" "$4 ; print Subject, $5, $6, "\n" Subject, $8, $9, "\n" Subject, $10, $11 }' b 

Allthough, это печатает вывод, что это не очень элегантно. Однако вы чувствуете себя с полями.

Когда awk разбивает строку на поля, я делаю это, говоря, что одно поле - любое поле, окруженное пробелами, т. Е. Вы можете изменить то, что awk использует в качестве разделителя полей, используя параметр командной строки «-F» или явно указывая его в блоке BEGIN.

Блок BEGIN запускается как только, прежде чем awk даже посмотрит на файл.

Итак, вы можете сделать это:

awk 'BEGIN { FS=":" } { print $1, $2 }' a 

Output: Server1 - free space/60% 

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

awk 'BEGIN { FS=":" } { print $1 ":", $2 }' a 

# Or, by setting OFS - the Output Field Separator 
awk 'BEGIN { FS=":" ; OFS=":" } { print $1,$2 }' a 

Output: Server1 - free space:/60% 

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

$ awk 'BEGIN { FS=":" ; OFS=":" } { print $1,$2 "\n" $1, $3 "\n" $1, $4 }' a 

Server1 - free space:/60% 
Server1 - free space: /opt 40% 
Server1 - free space: /var 50% 

Но вы хотите, чтобы это был цикл, который дает вам гибкость в отношении количества файловых систем/полей, с которыми вы сталкиваетесь, где вы можете получить ответ Эд Мортона, где я только что переместил объявление FS (разделитель полей) и OFS (выходной разделитель полей) в BEGIN, блок:

$ awk 'BEGIN { FS=":" ; OFS=":" } {for (i=2;i<=NF;i++) print $1, $i}' a > b 
$ cat b 
Server1 - free space:/60% 
Server1 - free space: /opt 40% 
Server1 - free space: /var 50% 
Server2 - free space:/50% 
Server2 - free space: /opt 30% 
Server2 - free space: /var 60% 
Server3 - free space:/30% 
Server3 - free space: /opt 50% 
Server3 - free space: /var 40% 

Вы также конец блока, который запускается после того, как все строки обрабатываются:

$ awk 'BEGIN { FS=":" ; OFS=":" } 
    {servers++ ; for (i=2;i<=NF;i++) { print $1, $i ; sum++ } } 
    END { printf("\nParsed %i lines producing %i lines\n", servers, sum) }' a 
Server1 - free space:/60% 
Server1 - free space: /opt 40% 
Server1 - free space: /var 50% 
Server2 - free space:/50% 
Server2 - free space: /opt 30% 
Server2 - free space: /var 60% 
Server3 - free space:/30% 
Server3 - free space: /opt 50% 
Server3 - free space: /var 40% 

Parsed 3 lines producing 9 lines 
+1

Это не дает правильный вывод. –

+0

Пользователь не производит никаких предварительных работ. Это ставит его на пути. – sastorsl

+0

Сделано небольшое редактирование. – sastorsl

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