如何从#SOF到#EOF 的文件中检索行
in source.sh
#SOF
"Lorem ipsum dolor sit amet"
"Vivamus pretium enim"
"Est accumsan enim magnis"
#EOF
#SOF
"Eleifend tincidunt id justo"
"Tellus ut tincidunt vel ac a orci"
"Sapien Nullam Sed nunc"
"Vestibulum est accumsan enim"
#EOF
#SOF
"Consequat mauris mollis montes"
#EOF
我需要得到3个文件
in target_1.sh
"Lorem ipsum dolor sit amet"
"Vivamus pretium enim"
"Est accumsan enim magnis"
in target_2.sh
"Eleifend tincidunt id justo"
"Tellus ut tincidunt vel ac a orci"
"Sapien Nullam Sed nunc"
"Vestibulum est accumsan enim"
in target_3.sh
"Consequat mauris mollis montes"
告诉别人怎么做?谢谢你的帮助
您可以使用awk:
awk '/^#EOF$/ {do_print=0}
do_print {print > ("target_"f_index".sh")}
/^#SOF$/ {do_print=1; f_index++}' source.sh
输入/输出:
- 匹配有问题的示例
解释:
awk '...'
:调用awk,一个逐行操作文本文件的工具。由一组单引号括起来的指令提供给awk/^#EOF$/ {do_print=0}
:^
是"行首"的regex锚点,$
是"行尾"的锚点。这里我们要说的是,如果我们看到#EOF
是一行中唯一的东西,请关闭打印标志do_print
do_print {print > ("target_"f_index".sh")}
:这是为awk解析的每一行运行的。如果设置了do_print
标志,则将该行附加到具有f_index
指定的索引的输出文件中/^#SOF$/ {do_print=1; f_index++}
:同样,如果我们在一行上只看到#SOF
,则打开打印标志,并将f_index
增加一- 请注意,最后三件事是为每行评估的,这就是为什么我们首先查找EOF,然后打印行(如果适用),然后查找SOF——我们不想打印
#EOF
或#SOF
source.sh
:将输入文件的名称指定为awk
;救一只猫
awk将优雅地完成:
awk '
/^#EOF/{l=0}
l {
print > "target_" file ".sh"
}
/^#SOF/{l=1;file++}
' source.sh
处理后
$ ls -1t target_*
target_1.sh
target_2.sh
targer_3.sh
解释
l {}
与if (l==1) {}
相同,因为1
是awk
的真表达式
如果您只想使用bash(您唯一的一个标签),请尝试这样做:
#!/bin/bash
c=0
while read a; do
if [[ $a =~ ^#SOF ]]; then
l=1
((file++))
fi
[[ $a =~ ^#EOF ]] && l=0
if [[ ! $a =~ ^#SOF ]] && ((l==1)); then
echo $a >> "target_${file}.sh"
fi
done < input_file