匹配特定行中的一些正则表达式,并将这些行保存为bash中的数组

时间:2014-03-10 18:04:32

标签: regex arrays bash

我需要从文件中扫描特定标签的文本行,并将这些标签之间的任何内容存储到bash中的数组中。基本语法如下:

<description> "long, multiline text descriptions" </description>

其中的文本存储在数组中。

4 个答案:

答案 0 :(得分:1)

逐行读取文件并检查正则表达式:

arr=()
while read -r s; do
    [[ "$s" =~ "<description>"(.*)"</description>" ]] && arr+=("${BASH_REMATCH[1]}")
done < file

答案 1 :(得分:1)

这个BASH解决方案应该可以胜任。

arr=()
match=""
while read -r line; do
    if [[ $line =~ "<description>"(.*)"</description>" ]]; then
        arr+=("${BASH_REMATCH[1]}")
        continue
    elif [[ $line =~ "<description>"(.*) ]]; then
        match+="${BASH_REMATCH[1]}"
    fi
    if [[ $match ]] && [[ $line != *"</description>"* && $line != *"<description>"* ]]; then
        match+=" $line"
    elif [[ $match ]] && [[ $line =~ (.*)"</description>" ]]; then
        match+=" ${BASH_REMATCH[1]}"
        arr+=("$match")
        match=""
    fi
done < file

答案 2 :(得分:1)

此实现需要xmlstarlet(http://xmlstar.sourceforge.net/)并假设内容中不存在EOT(传输结束)字符。它具有与基于真正的XML解析器相关的优点 - 实体被处理,注释被忽略,CDATA按字面解释等等。

descriptions=()
while IFS='' read -r -d $'\x04'; do
  descriptions+=( "$REPLY" )
done < <(xmlstarlet sel -m -t -v //description -o $'\x04')

答案 3 :(得分:0)

首先是一个小测试脚本:

cat <<EOF >find-tag.sh
#!/bin/bash
# find-tag.sh TARGET XMLFILE
target="$1"
awk "/<description>/   { keep=1; s=\"\" ; next}
     /<\/description>/ { keep=0; if (s ~ /$target/) { print s } ; next}
     {if (keep) { s = s \$0 }}
    " $2
EOF

接下来是一个带有多行条目的小型XML数据文件:

cat test.xml
<blah1>
  xxx
</blah1>
<description>
  blah1 blah1 blah1
  blah12 blah12 blah12
</description>
<description>
  blah2 blah2 blah2
  blah2a blah2a blah2a
</description>
<description>
  blah3 blah3 blah3
  blah3b blah3b blah3b
</description>
<description>
  blah4 blah4 blah4
  blah4c blah4c blah4c
</description>

最后,样本运行 - 来自find-tag.sh的每一行数据都是一个条目,它被读入数组data。然后显示data数组,每行一个项目。

data=()
# extract tagged entries to a file
./find-tag.sh blah test.xml >/tmp/xml

# read the XML extracts into the 'data' array
readarray -t data </tmp/xml

如果您的bash不支持readarray,请改用:

while read line ; do data=( "${data[@]}" "$line" ) ; done </tmp/xml

显示数据(显示数组项):

for ((i=0; i<${#data[@]}; i++)) ; do printf "line %d: %s\n" $i "${data[$i]}" ; done
line 0:   blah1 blah1 blah1  blah12 blah12 blah12  blah13 blah13 blah13
line 1:   blah2 blah2 blah2  blah2a blah2a blah2a
line 2:   blah3 blah3 blah3  blah3b blah3b blah3b
line 3:   blah4 blah4 blah4  blah4c blah4c blah4c

顺便说一句,你可以在https://github.com/aks/bash-lib#list_utils

找到一些有用的阵列管理实用程序