2

I have a array called arrayvar, which is being defined as

arrayvar=( $(awk '/'"$vovar"'/,/}/ {gsub("'"$vovar"'"," "); gsub("}"," "); gsub("{"," ");gsub(","," ");print}' temp1 | tr -d '\n' | sed 's/^[ \t]*//' | sed 's/[ \t]*$//') )

with

vovar=VARIABLES

My temp file has some variables which I am grabbing using the above command and the tr sed commands to remove spaces.
TEMP file

        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

When I run this command only arrayvar[0] is stripped of its values like this:

echo "${arrayvar[0]}"
a9EventCode

echo "${arrayvar[1]}"
            a9ControllerNumber

echo "${arrayvar[2]}"
            a9ChannelNumber

echo "${arrayvar[3]}"
            a9TargetNumber

Any help will be appreciated. Thanks!

  • you want to put the strings between { and } as array elements ? – heemayl Jul 1 '15 at 9:07
  • yeah whatever is between the { } brackets after VARIABLES. Warning , those strings may vary, they could all be in a single line, multiple strings in multiple line, only one string with in the {} and one string in one line (like the example above). The DESCRIPTION after } may or maynot be there. Same goes for ENTERPRISE. Only thing that separates the strings in the { } are, . Which may not be there when we have only one string between { }. – SamFlynn Jul 1 '15 at 9:15
  • You meant a9EventCode, a9ControllerNumber could be in a single line ? what would be the separator then ? also add some practical examples to your question you have mentioned in the comment.. – heemayl Jul 1 '15 at 9:22
  • @heemayl I had already asked this question before and muru gave me a solution, which works, however there are some extra spaces in each array element, that all I want to remove. If you have a way to directly input these strings without space then please help me out. My Previous Question – SamFlynn Jul 1 '15 at 9:30
1

You could use this:

var=( $(< input awk '/VARIABLES {/, /}/ {if ($0~/VARIABLES/||$0~/}/) next; else gsub(/[ ,]/, "", $0); print}') )
  • prints every record between a record matching VARIABLES { and a record matching }, removing every and , character

However I'd rather use mapfile and a single fork in place of a double fork to store values into an array:

mapfile var < <(< input awk '/VARIABLES {/, /}/ {if ($0~/VARIABLES/||$0~/}/) next; else gsub(/[ ,]/, "", $0); print}')
  • Yeah mapfile seems easier to use! thanks. – SamFlynn Jul 2 '15 at 4:43
1

Using later versions of GNU grep (comes with Ubuntu) that has -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 makes grep to treat the lines of input text separated by ASCII NUL instead of newlines so we can match newlines literally.

  • The PCRE pattern \s+VARIABLES\s+{\K[^}]+(?=}) will match the text inside {}

  • Then we have removed the white spaces (space, tab, newline) by tr -d '[:space:]'

  • As the IFS is set to , we can create the array with comma separated strings.

1

Do everything with awk as below:

arrayvar=($(awk '/'"$vovar"'/,/}/ {gsub("'"$vovar"'"," "); gsub("}"," "); gsub("{"," ");gsub(","," ");all=all$0} END {print all}' temp1 ))
1

Using 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>

Explanation

  • exit if ($start == 1 && /}/ );

    Exit the script if there is an } if VARIABLES (vovar) is passed

  • if ($start == 1) {s/\s*([0-9]|\w+)(,|)/$1/g; printf "%s",$_}

    Print the line if VARIABLES (vovar) is passed

  • $start=1 if (/'"$vovar"'/)

    Set the start marker if VARIABLES (vovar) is passed


Example

$ 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.