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!

4
  • you want to put the strings between { and } as array elements ?
    – heemayl
    Jul 1, 2015 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, 2015 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, 2015 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, 2015 at 9:30

4 Answers 4

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}')
0
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .