首先,我们有一个包含以下几行的文件,名为
datafile.txt
1 some test lines here
but not all lines contain nubers
3 and here is the last one
我们有一个 bash 变量
$ADDED
,其中包含要添加的行内容
ADDED="==This is the new line=="
ADDED="==This is the new line=="
< datafile.txt sed "1a \\
$ADDED
"
结果:
1 some test lines here
==This is the new line==
but not all lines contain nubers
3 and here is the last line
< datafile.txt sed "/^[0-9]/a \\
$ADDED
"
结果:
1 some test lines here
==This is the new line==
but not all lines contain nubers
3 and here is the last line
==This is the new line==
< datafile.txt sed "1i \\
$ADDED
"
结果
==This is the new line==
1 some test lines here
but not all lines contain nubers
3 and here is the last line
< datafile.txt sed "/all/s/$/\\
$ADDED/"
上面的示例通过替换在包含单词“all”的行后面添加行
1 some test lines here
but not all lines contain nubers
==This is the new line==
3 and here is the last line
< datafile.txt sed "/all/s/\(.*lines \)\(.*\)/\1\\
$ADDED\\
\2/"
上面将搜索包含单词“all”的行,并将其拆分在单词“lines”之后。结果:
1 some test lines here
but not all lines
==This is the new line==
contain nubers
3 and here is the last line
最后一件事。使用正则表达式无法解析 HTML,请检查 sputnik 评论中的链接。
但是,这并不意味着不可能匹配 HTML 文件的某些部分。如果你知道你想要什么 match (而不是解析) - 你也可以安全地使用 HTML 的正则表达式。简单来说,这里很多人不知道解析和匹配之间的区别。
因此,如果您的 html 文件具有众所周知的结构,例如你确信你的html将一直是上述结构,你可以放心地写:
<your_file.html sed "/^<tr><th>/a \\
<tr><td>new Row:1 Cell:1</td><td>Row:1 Cell:2</td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td>
"
你会得到
<table id="tfhover" class="tftable" border="1">
<tr><th>HEADER1</th><th>HEADER2</th><th>HEADER3</th><th>HEADER4</th></tr>
<tr><td>new Row:1 Cell:1</td><td>Row:1 Cell:2</td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td>
<tr><td>Row:1 Cell:1</td><td>Row:1 Cell:2</td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td></tr>
</table>
仅仅因为我们不解析 html 代码,我们只是匹配一些线条图案..
使用Perl
~$ perl -pe 'BEGIN {$str = q(<table id="tfhover" class="tftable" border="1">)}; \
s{\Q$str\E}{$&\n<tr><td>Row:1 Cell:1</td><td>Row:1 Cell:2<td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td>};' file
#OR
~$ perl -pe 'BEGIN {$str = q(<table id="tfhover" class="tftable" border="1">)}; \
s{(\Q$str\E)}{$1\n<tr><td>Row:1 Cell:1</td><td>Row:1 Cell:2<td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td>};' file
使用 Raku(以前称为 Perl_6)
~$ raku -pe 'BEGIN my $str = Q[<table id="tfhover" class="tftable" border="1">]; \
s{$str} = "$/\n<tr><td>Row:1 Cell:1</td><td>Row:1 Cell:2<td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td>";' file
#OR
~$ raku -pe 'BEGIN my $str = Q[<table id="tfhover" class="tftable" border="1">]; \
s{($str)} = "$0\n<tr><td>Row:1 Cell:1</td><td>Row:1 Cell:2<td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td>";' file
以上是用 Perl 和 Raku 编码的答案。在两种语言中,
$str
都被分配了一个单引号(即非插值)目标行,以插入到OP的第一行文本之后。两个答案都使用 \nnewtextline
插入新文本行(即 \n
已针对两种语言正确插入)。
s///
运算符的 RHS(识别域)实际上是一个双引号字符串。因此,要禁用正则表达式插值,必须使用 \Q … \E
形式。请注意,Raku 需要 my
关键字,并且最好使用方括号。Q
是最简单的引用结构:即使反斜杠会截断字符串,也不会被接受(如果你想转义内部反斜杠,请使用 q
)。对于每种语言的第一个答案,识别的字符串将替换为匹配变量,即 Perl 中的
$&
和 Raku 中的 $/
。
对于每种语言的第二个答案,使用枚举捕获。在这两种语言中,
()
括号用于表示枚举捕获;请注意,Raku 中的捕获是从 $0
开始的。
示例输入:
<table id="tfhover" class="tftable" border="1">
<tr><th>HEADER1</th><th>HEADER2</th><th>HEADER3</th><th>HEADER4</th></tr>
<tr><td>Row:1 Cell:1</td><td>Row:1 Cell:2</td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td></tr>
</table>
示例输出(所有四个代码示例):
<table id="tfhover" class="tftable" border="1">
<tr><td>Row:1 Cell:1</td><td>Row:1 Cell:2</td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td>
<tr><th>HEADER1</th><th>HEADER2</th><th>HEADER3</th><th>HEADER4</th></tr>
<tr><td>Row:1 Cell:1</td><td>Row:1 Cell:2</td><td>Row:1 Cell:3</td><td>Row:1 Cell:4</td></tr>
</table>
https://perldoc.perl.org/perlre
https://perldoc.perl.org/functions/quotemeta
https://docs.raku.org/language/regexes
https://docs.raku.org/language/quoting