Reputation: 298
i was just looking around but i didn't find anything that works for me. I would like to insert a new line (basically an html table row) on top of the other rows.
<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>
So, is there anyone that can suggest me a sed cmd that will insert a new:
<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>
just below the HEADERS?
Thanks!
Upvotes: 0
Views: 8922
Reputation: 2341
Using 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
Using Raku (formerly known as 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
Above are answers coded in Perl and Raku. In both languages $str
is assigned a single-quoted (i.e. non-interpolated) target line to insert after--the OP's first line of text. So to clarify (similar to the answer by @clt60), HTML isn't being "parsed" here--instead a single line of HTML is matched with a literal string, and a \n
newline and new text is inserted afterwards (e.g. \nnewtextinserted
).
The -pe
command-line flags in both Perl and Raku invoke sed
-like behavior, and answers in both languages use a match or capture variable in the replacement half of the s///
operator (followed by the aforementioned \nnewtextinserted
).
Here in Perl to save on backslashing custom delimiters are used, i.e. s{…}{…}
. Same in Raku, but also the use of custom delimiters has changed somewhat: in addition to things like s!foo!bar!
you can use the s{…} = "…"
format. To explain from the Raku docs: "Paired characters, like curly braces, are used only on the match portion, with the substitution given by assignment (of anything: a string, a routine call, etc.)."
In Perl the LHS (recognition domain) of the s///
operator is effectively a double-quoted string. So to disable regex interpolation the \Q…\E
form must be used in Perl. By comparison, note that 1). Raku escapes characters in single-quoted strings by default, 2). Raku requires the my
keyword, and 3). in Raku quoting constructs square brackets are preferable.
In Raku, Q
is the plainest-of-the-plain quoting construct: even backslashes that would otherwise truncate the string are not honored (use q
if you want internal backslashes escaped). Quoting constructs are quite varied/plentiful in Raku: see the final URL at bottom.
Sample Input:
<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>
Sample Output (all four code examples):
<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
Upvotes: 0
Reputation: 63974
So for the start, we have a file with the following lines, called datafile.txt
1 some test lines here
but not all lines contain nubers
3 and here is the last one
and we have one bash variable $ADDED
with the line content what want add
ADDED="==This is the new line=="
ADDED="==This is the new line=="
< datafile.txt sed "1a \\
$ADDED
"
the result:
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
"
the result:
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
"
result
==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/"
the above example add line after the line what contains word "all" by substitution
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/"
the above will search for the line what contains the word "all" and split it after the word "lines". The result:
1 some test lines here
but not all lines
==This is the new line==
contain nubers
3 and here is the last line
Last thing. It is impossible to parsing HTML with regural expressions, check the link in sputnik's comment.
BUT, that's not mean than it is impossible match some parts of HTML files. If you know what you want match (and not parse) - you can safely use regular expression for HTML too. Simply, many peoples here don't know the difference between parsing and matching.
So, if your html files has well known structure, e.g. you are sure than your html will the above structure all times, you can safely write:
<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>
"
and you will get
<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>
simply because we NOT PARSING the html code, we are only MATCHING some line patterns..
Upvotes: 9