【问题标题】:Save Each Multiline Grep Output To Array Record将每个多行 Grep 输出保存到数组记录
【发布时间】:2016-07-27 09:33:34
【问题描述】:

我正在使用正则表达式解析 XML。这是众所周知的,因此无需担心转义等和正确的 XML 解析。

grep 正在返回多行,我想将每个匹配项存储到一个文件中。

但是,我要么在数组 array=( $list ) 中的标签之间获取每一行,要么得到整个输出 array=( "$list" )

如何从 grep 循环遍历每个匹配项?

我的脚本目前如下所示:

#!/bin/bash

list=$(cat result.xml|grep -ozP '(?s)<tagname.*?tagname>')
array=( "$list" )
arraySize=${#array[@]}
for ((i = 0; i <= $arraySize; i += 1)); do
  match="${array[$i]}"
  echo "$match" > "$i".xml
done

【问题讨论】:

  • 你能展示来自result.xml的样本数据吗?

标签: regex bash


【解决方案1】:

直接将你的行放到一个while循环中

my_spliting_command | grep something | while read line
do
    echo $line >myoutputfile.txt
done

【讨论】:

    【解决方案2】:

    根据this answer,即将发布的grep 版本将更改-z 标志的含义,以便输入和输出 都以NUL 结尾。所以它会自动做你想做的事,但它只能在今天通过从 git 存储库下载和构建 grep 来使用。

    同时,一个相当老套的替代方法是使用-Z 标志,它以NUL 字符终止文件名。这意味着您需要打印一个“文件名”,您可以使用-H --label= 来完成。这将打印一个空文件名,后跟一个 NUL before 每个匹配,这不是很理想,因为你真的想要 NUL after 每个匹配。但是,以下应该有效:

    grep -ozZPH --label= '(?s)<tagname.*?tagname>' < result.xml | {
      i=0
      while IFS= read -rd '' chunk || [[ $chunk ]]; do
        if ((i)); then
          echo "$chunk" > $i.xml
        fi
        ((++i))
      done
    }
    

    【讨论】:

    • 你的意思是((++i))? ;-) 。哇,-ozZPH ...grep 从太阳 4 天开始就长大了 ;-) 祝大家好运。
    • @shellter- 哇,很多错别字。希望修复,谢谢。也许 -PHozZ 会更酷:)
    • -PHozZ 哈哈,grep 有更多选项的另一个好处 ;-) .
    【解决方案3】:

    您可以先使用grep 获取所有匹配项,然后使用awk 将每个匹配的模式保存到单独的文件中(例如file1.xml、file2.xml 等):

    cat result.xml | grep -Pzo '(?s)(.)<tagname.*?tagname>(.)' | awk '{ print $0 > "file" NR ".xml" }' RS='\n\n'   
    

    【讨论】:

      猜你喜欢
      • 2012-10-06
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 2021-01-10
      • 2014-09-13
      • 2016-01-31
      相关资源
      最近更新 更多