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之类的东西来做吗?