2

如何从#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"

告诉别人怎么做?谢谢您的帮助

4

3 回答 3

4

你可以用做到这一点:

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}:是“行首”的^正则表达式锚,是“行$尾”的锚。在这里我们说,如果我们看到#EOF一行中唯一的东西,请关闭打印标志do_print
  • do_print {print > ("target_"f_index".sh")}:这是为 awk 解析的每一行运行的。如果do_print设置了标志,则将该行附加到具有指定索引的输出文件中f_index
  • /^#SOF$/ {do_print=1; f_index++}: 同样,如果我们只看到#SOF一行,打开打印标志,然后加f_index一。
  • 请注意,最后 3 件事是为每行评估的,这就是为什么我们首先查找 EOF,然后打印该行(如果适用),然后再查找 SOF - 我们不想打印#EOF#SOF.
  • source.sh:指定输入文件的名称awk;拯救一只猫。
于 2012-12-09T18:55:14.273 回答
4

会优雅地做到这一点:

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
于 2012-12-09T18:56:46.783 回答
0

如果您只想使用(您只有一个标签),请尝试这样做:

#!/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
于 2012-12-09T19:23:00.813 回答