У меня есть массив с именем arrayvar
, который определяется как
arrayvar=( $(awk '/'"$vovar"'/, / ) {gsub("'"$vovar"'"," "); gsub("}"," "); gsub("{"," ");gsub(","," ");print}' temp1 | tr -d '\n' | sed 's/^[ \t]*//' | sed 's/[ \t]*$//') )
с
vovar=VARIABLES
В моем временном файле есть некоторые переменные, которые я извлекаю с помощью указанной выше команды и tr
sed
команд для удаления пробелов.
Файл TEMP
ENTERPRISE eMylexRaidEventInformation ПЕРЕМЕННЫЕ { a9EventCode, a9НомерКонтроллера, a9НомерКанала, a9TargetNumber, a9LunНомер, a9EventTimeStamp } ОПИСАНИЕ «устройство вышло в онлайн». --#SUMMARY "[Событие %d ctl %d chn %d tgt %d lun %d Время %d :] устройство перешло в режим онлайн." --#АРГУМЕНТЫ {0,1,2,3,4,5} --#СЕРЬЕЗНОСТЬ ИНФОРМАЦИОННАЯ --#TIMEINDEX 5 --#СОСТОЯНИЕ ЭКСПЛУАТАЦИОННОЕ ::= 1
При запуске этой команды arrayvar[0]
удаляются только ее значения, например:
эхо "${arrayvar[0]}" a9EventCode эхо "${arrayvar[1]}" a9НомерКонтроллера эхо "${arrayvar[2]}" a9НомерКанала эхо "${arrayvar[3]}" a9TargetNumber
Любая помощь будет оценена по достоинству. Спасибо!
решение1
Вы можете использовать это:
var=( $(< input awk '/VARIABLES {/, /}/ {if ($0~/VARIABLES/||$0~/}/) next; else gsub(/[ ,]/, "", $0); print}') )
- печатает каждую запись между записью, соответствующей
VARIABLES {
и записью, соответствующей}
, удаляя все символыи
,
Однако я бы предпочел использовать mapfile
одинарную вилку вместо двойной для сохранения значений в массиве:
mapfile var < <(< input awk '/VARIABLES {/, /}/ {if ($0~/VARIABLES/||$0~/}/) next; else gsub(/[ ,]/, "", $0); print}')
решение2
Использование более поздних версий GNU grep
(входит в состав Ubuntu), в которых есть -z
опция:
$ IFS=, arrayvar=( $(grep -Pzo '\s+VARIABLES\s+{\K[^}]+(?=})' temp1 | tr -d '[:space:]') )
$ echo "${arrayvar[0]}"
a9EventCode
$ echo "${arrayvar[1]}"
a9ControllerNumber
$ echo "${#arrayvar[@]}"
6
-z
опция позволяетgrep
обрабатывать строки входного текста, разделенные символами ASCII NUL, а не символами новой строки, чтобы мы могли буквально сопоставлять символы новой строки.Шаблон PCRE
\s+VARIABLES\s+{\K[^}]+(?=})
будет соответствовать тексту внутри{}
Затем мы удалили пробелы (пробелы, табуляции, символы новой строки)
tr -d '[:space:]'
Так как
IFS
установлено значение ,,
мы можем создать массив со строками, разделенными запятыми.
решение3
Сделайте все с помощью awk, как показано ниже:
arrayvar=($(awk '/'"$vovar"'/,/}/ {gsub("'"$vovar"'"," "); gsub("}"," "); gsub("{"," ");gsub(","," ");all=all$0} END {print all}' temp1 ))
решение4
С использованиемperl
perl -ne 'exit if ($start == 1 && /}/ ); if ($start == 1) {s/\s*([0-9]|\w+)(,|)/$1/g; printf "%s",$_}; $start=1 if (/'"$vovar"'/);' <your_input_file>
Объяснение
exit if ($start == 1 && /}/ );
Выйти из скрипта, если передан
}
ifVARIABLES
(vovar
)if ($start == 1) {s/\s*([0-9]|\w+)(,|)/$1/g; printf "%s",$_}
Распечатать строку, если
VARIABLES
(vovar
) передано$start=1 if (/'"$vovar"'/)
Установить начальный маркер, если
VARIABLES
(vovar
) пройден
Пример
$ vovar=VARIABLES
$ arrayvar=($(perl -ne 'exit if ($start == 1 && /}/ ); if ($start == 1) {s/\s*([0-9]|\w+)(,|)/$1/g; printf "%s",$_}; $start=1 if (/'"$vovar"'/);' foo))
$ for((i=0;i<${#arrayvar[@]};i++)); do echo "${arrayvar[i]}"; done
a9EventCode
a9ControllerNumber
a9ChannelNumber
a9TargetNumber
a9LunNumber
a9EventTimeStamp
$ cat foo
ENTERPRISE eMylexRaidEventInformation
VARIABLES {
a9EventCode,
a9ControllerNumber,
a9ChannelNumber,
a9TargetNumber,
a9LunNumber,
a9EventTimeStamp
}
DESCRIPTION
"device became online."
--#SUMMARY "[Event %d ctl %d chn %d tgt %d lun %d Time %d :] device became online."
--#ARGUMENTS {0,1,2,3,4,5}
--#SEVERITY INFORMATIONAL
--#TIMEINDEX 5
--#STATE OPERATIONAL
::= 1