我有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>
可变文本
我需要:
- 从MyInitialTextFile.txt中选择第一行(如果它们的开头相同(。就我而言,是前两行。然后将这两行转移到TransitionalTextFile.txt中。为此,我在bash中使用了head:
head -n 2 MyInitialTextFile.txt > TransitionalTextFile.txt
- 我将手动在它们上应用两个正则表达式的序列。对于我使用的正则表达式:
Find1:(\n(#,即查找换行符(键盘上的输入(
替换1:"也就是说,替换为5个空格
Find2:(.*(#即选择整个字符串
Replace2:$1\n#,即替换为所有选定的字符串(整个字符串(,并在末尾添加换行符。
将TransitionalTextFile.txt的内容传输到新文本文件的末尾,该文件的名称与第一个字符串Abc 1:2中的名称相同。为此,我使用了:
head -n 1 TransitionalTextFile.txt >> 'Abc 1:2.txt'
这将始终是-n 1,因为在regex步骤之后,即使最初选择了两个字符串,所有文本也会变成一个条目。
从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