它能将head、sed和regex组合成一个bash脚本吗



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

  • 每一行都以这个开头:<p><nsup></nsup> <b>
  • 后面是这样的表达式:Abc 1:2或2Ab 1:2
  • 始终跟在后面:<sup>
  • 之后是各种各样的文本

<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. MyInitialTextFile.txt中选择第一行(如果它们的开头相同(。就我而言,是前两行。然后将这两行转移到TransitionalTextFile.txt中。为此,我在bash中使用了head:
head -n 2 MyInitialTextFile.txt > TransitionalTextFile.txt
  1. 我将手动在它们上应用两个正则表达式的序列。对于我使用的正则表达式:

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

替换1:"也就是说,替换为5个空格

Find2:(.*(#即选择整个字符串

Replace2:$1\n#,即替换为所有选定的字符串(整个字符串(,并在末尾添加换行符。

  1. TransitionalTextFile.txt的内容传输到新文本文件的末尾,该文件的名称与第一个字符串Abc 1:2中的名称相同。为此,我使用了:

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

这将始终是-n 1,因为在regex步骤之后,即使最初选择了两个字符串,所有文本也会变成一个条目。

  1. MyInitialTextFile.txt中删除我传输的行数,对我来说有两行。为此,我在bash:中使用了sed

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

过程继续到下一行:<p><nsup></nsup> <b>Abc 1:3<sup>可变文本

我手动完成了以上四个步骤,但我的问题是如何将这四个步骤整合到一个脚本中。也就是说,从一个初始文件中选择字符串,并通过regex将它们传输到另一个文件,在那里我删除它们之间的换行符,并在它们的末尾添加换行符,使其看起来像这样:

<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($1==p) {                # if first part equals first part of previous split
b=b "     " $0         # 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($1,t,/<b>/)    # get the changing part
b=$0                   # reset buffer
}
p=$1                       # 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 >>s之后添加一个close(t[n])

sed中实现head很容易,因此通常不需要将两者结合。然而,您的问题似乎更适合Awk,它比sed这种相当神秘简洁的低级语言更容易阅读和编写。

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

awk '/^<p><nsup></nsup> <b>/ {
str = substr($0, 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, $0 >d
sep = "     "
}
END { if (d) printf "n" >d }' MyInitialTextFile.txt

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

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

最新更新