它可以将 head、sed 和 regex 一起工作到一个 bash 脚本中吗?

Can it work together head, sed and regex into one bash script?

MyInitialTextFile.txt 具有以下特征:<p><nsup></nsup> <b>Abc 1:2<sup>varied text.

<p><nsup></nsup> <b>Abc 1:2<sup>各种文字

<p><nsup></nsup> <b>Abc 1:2<sup>各种文字

<p><nsup></nsup> <b>Abc 1:3<sup>各种文字

<p><nsup></nsup> <b>Abc 1:4<sup>各种文字

<p><nsup></nsup> <b>Abc 1:4<sup>各种文字

<p><nsup></nsup> <b>Abc 1:4<sup>各种文字

我需要:

  1. Select 来自 MyInitialTextFile.txt 的第一行(如果它们的开头相同)。在我的例子中,前两行。然后把这两行转成一个TransitionalTextFile.txt 为此,我在 bash:
  2. 中使用了 head
head -n 2 MyInitialTextFile.txt > TransitionalTextFile.txt
  1. 我将在其中手动应用两个正则表达式的序列。 对于我使用的正则表达式:

Find1: (\n) #即查找换行符(键盘输入)

Replace1: " " #即替换为5个空格

Find2: (.*) #即select整个字符串

Replace2: $1\n #即替换为所有selected(整个字符串),最后加一个换行。

  1. TransitionalTextFile.txt的内容转移到与第一个字符串Abc中找到的同名的新文本文件的末尾1:2. 为此,我使用了:

    head -n 1 TransitionalTextFile.txt >> 'Abc 1:2.txt'

这将始终是 -n 1 因为在正则表达式步骤之后,所有文本都变成一个条目,即使最初有两个字符串 selected。

  1. MyInitialTextFile.txt中删除我转移的行数,对我来说有两行。 为此,我在 bash:

    中使用了 sed

    sed -i '1,2d' MyInitialTextFile.txt

然后该过程继续下一行: <p><nsup></nsup> <b>Abc 1:3<sup>各种文字

我手动完成了以上四个步骤,但我的问题是如何将所有这四个步骤整合到一个脚本中。也就是说,select 来自初始文件的字符串,并通过正则表达式将它们传输到另一个文件,我删除了它们之间的换行符,并在它们的末尾添加了一个换行符,这样它看起来像这样:

<p><nsup></nsup> <b>Abc 1:2<sup>各种文字 <p><nsup></nsup> <b>Abc 1:2<sup>各种文字

最后我必须从我的初始文件中删除这两个字符串。 如果能将这四个步骤整合到一个脚本中,我将不胜感激。 谢谢。

像这样(为团队拿一个:)?使用 awk(注意: 它创建类似 Abc 1:2<b><sup> 之间的任何文件):

$ awk '
BEGIN {
    FS="<sup>"                 # split at this delimiter
}
{
    if(==p) {                # if first part equals first part of previous split
        b=b "     " [=10=]         # append to the output buffer
    }
    else {                     # if first part differs, do stuff
        if(NR>1) {             # first line needs not printing
            print b >> t[n]
            # close t[n]       # uncomment if if needed
        }
        n=split(,t,/<b>/)    # get the changing part
        b=[=10=]                   # reset buffer
    }
    p=                       # create previous to compare on next round
}
END {
    print b >> t[n]            # flush the rest of the buffer
}' file

cat Abc\ 1\:2 的输出:

<p><nsup></nsup> <b>Abc 1:2<sup>varied text     <p><nsup></nsup> <b>Abc 1:2<sup>varied text

根据使用的 awk 风格,如果您从文件描述符开始 运行,请在 print >> 之后添加一个 close(t[n])

sed 中实现 head 很容易,因此通常没有必要将两者结合起来。但是,您的问题似乎更适合 Awk,它比 sed.

相当隐晦和简洁的低级语言更易于阅读和编写。

猜测一下您的预期输出应该是什么样子,试试这个。

awk '/^<p><nsup><\/nsup> <b>/ {
    str = substr([=10=], 21); split(str, n, /<sup>/);
    if (n[1] != id) {
        if (d) { printf "\n" >d; close (d) }
        d = n[1] ".txt"
        id = n[1]
        sep = ""
    }
    printf "%s%s", sep, [=10=] >d
    sep = "     "
    }
END { if (d) printf "\n" >d }' MyInitialTextFile.txt

这会提取 <b><sup> 之间的字符串,并将每一行写入以该字符串命名的文件,用五个空格替换换行符。

演示:https://ideone.com/79P4tk