我有一个巨大的.txt文件,格式如下(每个非空行以三个空格开头):

   unwanted text
   unwanted text

   *wanted text
   abc
   def

   *wanted text 2
   content
   content

   *wanted text 3
   content
   content

   (...)

我正在寻找一个只返回从第一个“*”ocurrence到(但不包括)第二个“*”ocurrence的行的代码。
在多个StackOverflow帖子中浏览,我使用Ubuntu(GNU/Linux)获得了以下工作代码:
sed -n -e '/^   \*/{p;q}' bigfile.txt && sed -e '1,/   \*/d' -e '/   \*/,$d' bigfile.txt

它提供了以下(按需)输出:
*wanted text
abc
def
\n (representing a wanted blank line)

尽管这正是我想要的输出,但你必须同意我的观点,这是一个有点愚蠢的代码,因为我必须使用sed两次。首先,我只有它的第二部分(在“&&”之后),除了第一行(*想要的文本)之外,我会返回正确的内容。然后我将代码的第一部分(在“&&”之前)追加到后面,这样我就得到了所需部分的第一行。我尝试过的每一段代码都没有给我带来更好的结果。
这永远不足以说明,这是一个很大的文件,我将在脚本中递归地执行此操作,因此,如果可能的话,a/q(在找到第一个结果后退出)更可取。
完成此操作后,我需要将最后一个命令的结果作为输入,这样就可以得到除先前结果之外的整个文本,例如:
   unwanted text
   unwanted text

   *wanted text 2
   content
   content

   *wanted text 3
   content
   content

   (...)

总之,我的两个问题是:
有没有一种方法可以用sed一行程序获得上面描述的第一个期望输出,而不需要调用sed两次(最好在找到摘录后退出,这样它就不会搜索所有大文件)?我很确定有一个更优雅的解决方案。
如何将“除了前一个问题的结果之外的整个文本”(如“反向”输出)作为输出?
我没有软件需求,我只需要它,这样我就可以运行
一次又一次地操作和“不断更新”输入并处理每个
根据具体情况输出第1个命令。
希望我说得够清楚。请问我有没有遗漏任何细节。
非常感谢您的关注!

最佳答案

去营救!

$ awk '$1~/^*/{if(f) exit; f=1} f' file

   *wanted text
   abc
   def
   <-- here is the empty line formatter eats

第二部分
$ awk '$1~/^*/{f++} !f||f>1' file

   unwanted text
   unwanted text

   *wanted text 2
   content
   content

   *wanted text 3
   content
   content

   (...)

09-26 01:42