我的文件格式如下:
[PATTERN]
line1
line2
line3
.
.
.
line
[PATTERN]
line1
line2
line3
.
.
.
line
[PATTERN]
line1
line2
line3
.
.
.
line
我想从上面的文件中提取以下块:
[PATTERN]
line1
line2
line3
.
.
.
line
注意:2 [PATTERN]之间的行数可能会有所不同,因此不能依赖行数。
基本上,我想将每个模式及其后面的行存储到数据库中,因此我必须在我的文件中迭代所有这些块。
如何使用Shell Scripting?
答案 0 :(得分:2)
这假设您使用bash作为shell。对于其他shell,实际的解决方案可能不同。
假设您的数据位于data
:
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]
。
这将创建文件file.1
,file.2
等
编辑:回应有关awk解决方案的请求:
awk '/^\[PATTERN\]$/{close("file"f);f++;next}{print $0 > "file"f}' data
想法是每次找到[PATTERN]
时跳过一个新文件(跳过该行 - next
命令),并将所有连续行写入该文件。如果您需要在生成的文件中包含[PATTERN]
,请删除next
命令。
注意[
和]
的转义,它们对正则表达式有特殊意义。如果您的模式不包含这些模式,则不需要转义。 ^
和$
是可取的,因为它们会将您的模式与您通常需要的行的开头和结尾联系起来。
答案 1 :(得分:0)
这肯定可以改进,但是如果你想在一个数组中存储行,这是我过去所做的事情:
#!/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[*]}
我不喜欢最后一组处理循环...