Arrays Bash:if条件子句,同时迭代二维属性文件

Arrays Bash:if条件子句,同时迭代二维属性文件,arrays,bash,shell,if-statement,properties-file,Arrays,Bash,Shell,If Statement,Properties File,我有一个由项[I]定义的数据结构——包含-->子项[k]。我想编写一个小的bash脚本,它解析子项,并在命中特定子项时执行操作 我的sampletext.properties文件如下所示: Item1.subitem1=tom Item1.subitem2=bob Item2.subitem1=alice Item2.subitem2=cindy 为了克服Bash中缺少二维数组的缺点,我编写了两个函数,一个用于获取键的值,另一个用于计算字符串的出现次数 然后,我构建一个for循环来解析这些项,

我有一个由项[I]定义的数据结构——包含-->子项[k]。我想编写一个小的bash脚本,它解析子项,并在命中特定子项时执行操作

我的sampletext.properties文件如下所示:

Item1.subitem1=tom
Item1.subitem2=bob
Item2.subitem1=alice
Item2.subitem2=cindy
为了克服Bash中缺少二维数组的缺点,我编写了两个函数,一个用于获取键的值,另一个用于计算字符串的出现次数

然后,我构建一个for循环来解析这些项,并尝试包含一个IF子句来点击“bob”并说些什么。不幸的是,脚本没有看到bob,而且IF子句似乎不起作用:

#!/bin/bash

# The input text file 
PROPERTY_FILE=sampletext.properties

#Defining a function to get the value of a key
function getProperty {
   PROP_KEY=$1
   PROP_VALUE=`cat $PROPERTY_FILE | grep "$PROP_KEY" | cut -d'=' -f2 | tr -d '\n'`
   echo $PROP_VALUE
}

# Counting the number of subitem1 entries
function countsubitem1 {
  toolsnumber=`cat $PROPERTY_FILE | grep "Item[0-9].subitem1" | wc -l`
  echo $toolsnumber
}
countsubitem1


for (( i=1; i<=$(countsubitem1); i++))
do
  subitem1=`getProperty "Item$i.subitem1"`
  subitem2=`getProperty "Item$i.subitem2"`
  echo item$i:$(getProperty "Item$i.subitem1") # Testing the getProperty function again
  echo subitem2:$subitem2 # Testing the for loop and the getProperty function
  if [[ "$subitem2" == "bob" ]]; then
    echo "I see bob!"
  else
    echo "No bob here!"
  fi  
done
我所期望的是:

./samplebash.sh
2
item1:tom
subitem2:bob
I see bob!
item2:alice
subitem2:cindy
No bob here!
我尝试了对IF条款的几处修改:

 if [ "$subitem2" == "bob" ]; then

但我总是听到“这里没有鲍勃!”留言。

谢谢@William Pursell的提示

添加一个
|tr-d'\r'
清理了字符串并正确解析了它

我现在获得:

item1subitem1:tom
subitem2:bob
I see bob!
item2subitem2:alice
subitem2:cindy
No bob here!
使用代码:

#!/bin/bash

# The input text file 
PROPERTY_FILE=sampletext.properties

#Defining a function to get the value of a key
function getProperty {
   PROP_KEY=$1
   PROP_VALUE=`cat $PROPERTY_FILE | grep "$PROP_KEY" | cut -d'=' -f2 | tr -d '\n' | tr -d '\r'`
   echo $PROP_VALUE
}

# Counting the number of subitem1 entries
function countsubitem1 {
  toolsnumber=`cat $PROPERTY_FILE | grep "Item[0-9].subitem1" | wc -l`
  echo $toolsnumber
}


for (( i=1; i<=$(countsubitem1); i++))
do
  subitem1=`getProperty "Item$i.subitem1"`
  subitem2=`getProperty "Item$i.subitem2"`
  echo item"$i"subitem$i:$(getProperty "Item$i.subitem1") # Testing the getProperty function again
  echo subitem2:$subitem2 # Testing the for loop and the getProperty function
  if [[ "$subitem2" == "bob" ]]; then
    echo "I see bob!"
  else
    echo "No bob here!"
  fi  
done
#/bin/bash
#输入文本文件
PROPERTY\u FILE=sampletext.properties
#定义函数以获取键的值
函数getProperty{
道具钥匙=1美元
PROP_VALUE=`cat$PROPERTY_FILE | grep“$PROP_KEY”| cut-d'='-f2 | tr-d'\n'| tr-d'\r'`
echo$PROP_值
}
#计算子项1条目的数量
函数countsubitem1{
toolsnumber=`cat$PROPERTY|U文件| grep“项[0-9]。子项1“| wc-l”`
echo$toolsnumber
}

(i=1;i感谢@William Pursell的提示

添加一个
|tr-d'\r'
清理了字符串并正确解析了它

我现在获得:

item1subitem1:tom
subitem2:bob
I see bob!
item2subitem2:alice
subitem2:cindy
No bob here!
使用代码:

#!/bin/bash

# The input text file 
PROPERTY_FILE=sampletext.properties

#Defining a function to get the value of a key
function getProperty {
   PROP_KEY=$1
   PROP_VALUE=`cat $PROPERTY_FILE | grep "$PROP_KEY" | cut -d'=' -f2 | tr -d '\n' | tr -d '\r'`
   echo $PROP_VALUE
}

# Counting the number of subitem1 entries
function countsubitem1 {
  toolsnumber=`cat $PROPERTY_FILE | grep "Item[0-9].subitem1" | wc -l`
  echo $toolsnumber
}


for (( i=1; i<=$(countsubitem1); i++))
do
  subitem1=`getProperty "Item$i.subitem1"`
  subitem2=`getProperty "Item$i.subitem2"`
  echo item"$i"subitem$i:$(getProperty "Item$i.subitem1") # Testing the getProperty function again
  echo subitem2:$subitem2 # Testing the for loop and the getProperty function
  if [[ "$subitem2" == "bob" ]]; then
    echo "I see bob!"
  else
    echo "No bob here!"
  fi  
done
!/bin/bash
#输入文本文件
PROPERTY\u FILE=sampletext.properties
#定义函数以获取键的值
函数getProperty{
道具钥匙=1美元
PROP_VALUE=`cat$PROPERTY_FILE | grep“$PROP_KEY”| cut-d'='-f2 | tr-d'\n'| tr-d'\r'`
echo$PROP_值
}
#计算子项1条目的数量
函数countsubitem1{
toolsnumber=`cat$PROPERTY|U文件| grep“项[0-9]。子项1“| wc-l”`
echo$toolsnumber
}

对于((i=1;i)请考虑此代码:

readarray -t arr < "$PROPERTY_FILE"
getitem () {
    for i in "${arr[@]}"; {
        read item subitem value <<< ${i//[.=]/ }
        case ${1:-1}${2:-2} in $item$subitem|${item}2|1$subitem)
            echo "item=$item subitem=$subitem value=$value";;
        esac
    }
}

请考虑此代码:

readarray -t arr < "$PROPERTY_FILE"
getitem () {
    for i in "${arr[@]}"; {
        read item subitem value <<< ${i//[.=]/ }
        case ${1:-1}${2:-2} in $item$subitem|${item}2|1$subitem)
            echo "item=$item subitem=$subitem value=$value";;
        esac
    }
}

使用关联数组

#!/bin/bash

# The input text file 
PROPERTY_FILE=sampletext.properties


# Load the properties file
#
declare -A properties

loadProperties() {
    local key value

    if [[ "${#properties[@]}" -eq 0 ]]
    then
        # Lazy load the properties file
        # Strip Windows-style CR as we go
        #
        while IFS='=' read -r key value
        do
            properties[$key]="$value"

        done < <(tr -d '\r' <"$PROPERTY_FILE")
    fi
}


# Get the value of a key
#
getProperty() {
    local key="$1"

    loadProperties
    echo "${properties[$key]}"
}

    
# Count the number of "subitem1" items
#
countsubitem1() {
    loadProperties
    printf "%s\n" "${!properties[@]}" | awk -F. '$2 == "subitem1"' | wc -l
}

不要使用不推荐使用的
函数
关键字来声明函数。尽量使用小写变量名,这样您的变量名就不会与标准变量冲突,例如
$PATH
。使用
$(…)
而不是反勾号来括起需要执行的值。

使用关联数组

#!/bin/bash

# The input text file 
PROPERTY_FILE=sampletext.properties


# Load the properties file
#
declare -A properties

loadProperties() {
    local key value

    if [[ "${#properties[@]}" -eq 0 ]]
    then
        # Lazy load the properties file
        # Strip Windows-style CR as we go
        #
        while IFS='=' read -r key value
        do
            properties[$key]="$value"

        done < <(tr -d '\r' <"$PROPERTY_FILE")
    fi
}


# Get the value of a key
#
getProperty() {
    local key="$1"

    loadProperties
    echo "${properties[$key]}"
}

    
# Count the number of "subitem1" items
#
countsubitem1() {
    loadProperties
    printf "%s\n" "${!properties[@]}" | awk -F. '$2 == "subitem1"' | wc -l
}

不要使用不推荐使用的
函数
关键字来声明函数。尽量使用小写变量名,以免与标准变量(如
$PATH
)冲突。请使用
$(…)
而不是反勾号来括起需要执行的值。

您尝试的替代方法没有多大意义,但是您是否验证了存储在
子项2中的值不包含尾随空格?您是否有Bash 4+来使用关联数组,而不是低效地打开、关闭和解析整个文件是否按键对每个属性进行寻址?您好user1934428,谢谢您的时间。我试图在属性值定义中添加| sed的//*$//g'以删除结尾尾随空格,但不幸的是,我看不到任何区别尾随
\r
?Pet peeve-。您尝试的替代方法没有多大意义,但您是否验证了va存储在
子项2
中的lue不包含尾随空格?在按键寻址每个属性时,Bash 4+是否可以使用关联数组,而不是低效地打开、关闭和解析整个文件?您好user1934428,谢谢您的时间。我尝试将| sed's/*$//g'添加到属性值定义中以删除结尾尾随空格,但不幸的是,我看不到任何区别尾随
\r
?宠物皮-。