Bash 如何提取模式之间的线条?

Bash 如何提取模式之间的线条?,bash,shell,scripting,sed,grep,Bash,Shell,Scripting,Sed,Grep,我有一个格式如下的文件: [PATTERN] line1 line2 line3 . . . line [PATTERN] line1 line2 line3 . . . line [PATTERN] line1 line2 line3 . . . line 我想从上述文件中提取以下块: [PATTERN] line1 line2 line3 . . . line 注意:2[PATTERN]之间的行数可能不同,因此不能依赖行数 基本上,我希望将每个模式及其后的行存储到数据库中,因此我必须在文

我有一个格式如下的文件:

[PATTERN]
line1
line2
line3
.
.
.
line
[PATTERN]
line1
line2
line3
.
.
.
line
[PATTERN]
line1
line2
line3
.
.
.
line
我想从上述文件中提取以下块:

[PATTERN]
line1
line2
line3
.
.
.
line
注意:2[PATTERN]之间的行数可能不同,因此不能依赖行数

基本上,我希望将每个模式及其后的行存储到数据库中,因此我必须在文件中迭代所有这些块


如何使用Shell脚本实现这一点?

这假设您使用的是bash作为Shell。对于其他壳,实际解决方案可能不同

假设您的数据在
数据中

i=0 ; cat data  | while read line ; do \
  if [ "$line" == "[PATTERN]" ] ; then \
    i=$(($i + 1)) ; touch file.$i ; continue ; \
  fi ; echo "$line" >> file.$i ; \
done
根据实际的分离模式更改
[PATTERN]

这将创建文件
文件.1
文件.2
,等等

编辑:响应有关awk解决方案的请求:

awk '/^\[PATTERN\]$/{close("file"f);f++;next}{print $0 > "file"f}' data
其思想是在每次找到
[PATTERN]
时打开一个新文件(跳过该行-
next
命令),并将所有后续行写入该文件。如果需要在生成的文件中包含
[PATTERN]
,请删除
next
命令


注意
[
]
的转义,它们对正则表达式有特殊意义。如果您的模式不包含这些,则不需要转义。
^
$
是可取的,因为它们将您的模式绑定到行首和行尾,这通常是您需要的。

这当然可以得到改进,但如果您想在数组中存储行,我以前做过一些事情:

#!/bin/bash
file=$1
gp_cnt=-1
i=-1

while read line
do
  # Match pattern
  if [[ "$line" == "[PATTERN]" ]]; then
    let "gp_cnt +=1"
    # If this is not the first match process group
    if [[ $gp_cnt -gt 0 ]]; then
      # Process the group
      echo "Processing group #`expr $gp_cnt - 1`"
      echo ${parsed[*]}
    fi
    # Start new group
    echo "Pattern #$gp_cnt catched"
    i=0
    unset parsed
    parsed[$i]="$line"

    # Other lines (lines before first pattern are not processed)
  elif [[ $gp_cnt != -1 ]]; then
    let "i +=1"
    parsed[$i]="$line"
  fi
done < <(cat $file)

# Process last group
echo "Processing group #$gp_cnt"
echo ${parsed[*]}
#/bin/bash
文件=$1
gp_cnt=-1
i=-1
读行时
做
#匹配模式
如果[[“$line”==“[PATTERN]”];然后
设“gp_cnt+=1”
#如果这不是第一个匹配过程组
如果[$gp_cnt-gt 0]];然后
#处理组
echo“处理组#`expr$gp#u cnt-1”
echo${parsed[*]}
fi
#创建新组
回显“图案#$gp_cnt已捕获”
i=0
未解析
已解析[$i]=“$line”
#其他行(不处理第一个图案之前的行)
elif[$gp_cnt!=-1]];然后
设“i+=1”
已解析[$i]=“$line”
fi

这真是模棱两可。您想提取哪一个?请询问您的问题。。我知道这似乎模棱两可,但很难解释。重复的,或者也许?解决方案是正确的。。但是我们可以直接用sed、awk、grep之类的东西来做吗?