Ich habe ein Array namensarrayvar
, das wie folgt definiert wird:
arrayvar=( $(awk '/'"$vovar"'/,/}/ {gsub("'"$vovar"'"," "); gsub("}"," "); gsub("{"," ");gsub(","," ");print}' temp1 | tr -d '\n' | sed 's/^[ \t]*//' | sed 's/[ \t]*$//') )
mit
vovar=VARIABLES
Meine temporäre Datei enthält einige Variablen, die ich mit dem obigen Befehl und den tr
sed
Befehlen zum Entfernen von Leerzeichen abrufe.
TEMP-Datei
ENTERPRISE eMylexRaidEventInformation VARIABLEN { a9Ereigniscode, a9ControllerNummer, a9Kanalnummer, a9Zielnummer, a9LunNummer, a9EventTimeStamp } BESCHREIBUNG "Gerät ist online." --#SUMMARY "[Ereignis %d ctl %d chn %d tgt %d lun %d Zeit %d :] Gerät ist online gegangen." --#ARGUMENTE {0,1,2,3,4,5} --#SCHWEREGRAD INFORMATION --#ZEITINDEX 5 --#STATUS OPERATIONELL ::= 1
Wenn ich diesen Befehl ausführe, arrayvar[0]
werden nur seine Werte wie folgt entfernt:
echo "${arrayvar[0]}" a9Ereigniscode echo "${arrayvar[1]}" a9ControllerNummer echo "${arrayvar[2]}" a9Kanalnummer echo "${arrayvar[3]}" a9Zielnummer
Für jede Hilfe bin ich dankbar. Danke!
Antwort1
Sie könnten dies verwenden:
var=( $(< input awk '/VARIABLES {/, /}/ {if ($0~/VARIABLES/||$0~/}/) next; else gsub(/[ ,]/, "", $0); print}') )
- druckt jeden Datensatz zwischen einem Datensatz, der übereinstimmt,
VARIABLES {
und einem Datensatz, der übereinstimmt}
, und entfernt dabei jedesund
,
-Zeichen.
Ich würde jedoch mapfile
zum Speichern von Werten in einem Array lieber einen einzelnen Fork anstelle eines doppelten Forks verwenden:
mapfile var < <(< input awk '/VARIABLES {/, /}/ {if ($0~/VARIABLES/||$0~/}/) next; else gsub(/[ ,]/, "", $0); print}')
Antwort2
Bei Verwendung späterer Versionen von GNU grep
(wird mit Ubuntu geliefert) gibt es folgende -z
Option:
$ IFS=, arrayvar=( $(grep -Pzo '\s+VARIABLES\s+{\K[^}]+(?=})' temp1 | tr -d '[:space:]') )
$ echo "${arrayvar[0]}"
a9EventCode
$ echo "${arrayvar[1]}"
a9ControllerNumber
$ echo "${#arrayvar[@]}"
6
-z
Option bewirkt,grep
dass die durch ASCII NUL statt durch Zeilenumbrüche getrennten Eingabetextzeilen behandelt werden, sodass wir Zeilenumbrüche wörtlich abgleichen können.Das PCRE-Muster
\s+VARIABLES\s+{\K[^}]+(?=})
stimmt mit dem darin enthaltenen Text überein{}
Anschließend haben wir die Leerzeichen (Leerzeichen, Tabulator, Zeilenumbruch) entfernt durch
tr -d '[:space:]'
Da dies
IFS
auf eingestellt ist,,
können wir das Array mit durch Kommas getrennten Zeichenfolgen erstellen.
Antwort3
Machen Sie alles mit awk wie folgt:
arrayvar=($(awk '/'"$vovar"'/,/}/ {gsub("'"$vovar"'"," "); gsub("}"," "); gsub("{"," ");gsub(","," ");all=all$0} END {print all}' temp1 ))
Antwort4
Verwenden vonperl
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>
Erläuterung
exit if ($start == 1 && /}/ );
Beenden Sie das Skript, wenn ein
}
ifVARIABLES
(vovar
) übergeben wirdif ($start == 1) {s/\s*([0-9]|\w+)(,|)/$1/g; printf "%s",$_}
Drucken Sie die Zeile, wenn
VARIABLES
(vovar
) übergeben wird$start=1 if (/'"$vovar"'/)
Setzen Sie den Startmarker, wenn
VARIABLES
(vovar
) überschritten wird
Beispiel
$ 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