我想合并文件中的每一组行:
<tr>
<td >441</td>
<td >S</td>
<td >0,74</td>
</tr>
<tr>
<td >442</td>
<td >S</td>
<td >0,14</td>
</tr>
到一行(td 之间的空格或制表符的数量对我来说并不重要):
<tr> <td >441</td> <td >S</td> <td >0,74</td> </tr>
<tr> <td >442</td> <td >S</td> <td >0,14</td> </tr>
每个组(在 vi 中使用 ':set line')如下所示:
^I<tr>$
^I^I<td >441</td>$
^I^I<td >S</td>$
^I^I<td >0,74</td>$
^I</tr>$
我自己使用 sed 命令做这件事确实遇到了问题。任何帮助都将不胜感激。
答案1
这是一个使用 perl 而不是 sed 的解决方案。我发现这个解决方案更易于阅读和理解。
perl -pe 's|\n|| ; s|</tr>|</tr>\n|' file
输出:
<tr> <td >441</td> <td >S</td> <td >0,74</td></tr>
<tr> <td >442</td> <td >S</td> <td >0,14</td></tr>
答案2
使用 sed,您可以执行以下操作:
$ cat inf
<tr>
<td >441</td>
<td >S</td>
<td >0,74</td>
</tr>
$ sed ':a;N;s/\n//;ta' inf
<tr> <td >441</td> <td >S</td> <td >0,74</td> </tr>
这样做的目的是:
:a
做标签N
会将当前行附加到缓冲区,从而允许下一个命令s/\n//
将用空值替换上一个命令中的新行,从而有效地连接行ta
是“转到:a”
更简单的方法是使用tr
:
$ cat inf
<tr>
<td >441</td>
<td >S</td>
<td >0,74</td>
</tr>
$ cat inf|tr -d '\n'
<tr> <td >441</td> <td >S</td> <td >0,74</td> </tr>
意思-d '\n'
是“删除新行”。
编辑:误解了你想要什么。如果你想在一个输入流中处理上述多个组,你可以这样做sed
:
$ cat inf
foo
baz
<tr>
<td >441</td>
<td >S</td>
<td >0,74</td>
</tr>
fizz
buzz
<tr>
<td >441</td>
<td >S</td>
<td >0,74</td>
</tr>
tomato
potato
$ sed -r '/<tr/{:a;N;s/[\t\n]//g;/<\/tr/!ba}' inf
foo
baz
<tr><td >441</td><td >S</td><td >0,74</td></tr>
fizz
buzz
<tr><td >441</td><td >S</td><td >0,74</td></tr>
tomato
potato
awk
正如其他人提到的,你可以用或或python以更易读的形式执行此操作perl
,但请注意一件事 - regexp 不够强大,无法解析 HTML 或 XML。请参阅此文以获得更好的讨论:
希望这可以帮助。
答案3
# cat foo.html | xargs echo -n
<tr> <td >441</td> <td >S</td> <td >0,74</td> </tr>
或者删除所有空格......
# cat foo.html | xargs -n1 echo -n
<tr><td>441</td><td>S</td><td>0,74</td></tr>
你可以通过以下方式从 vi 内部实现这种效果:
!!xargs echo -n
答案4
sed -r ':k /<tr>/,/<\/tr>/{/<\/tr>/! {N;s/\n/ /;tk}}' file
$ cat file
<tr>
<td >441</td>
<td >S</td>
<td >0,74</td>
</tr>
<tr>
<td >442</td>
<td >S</td>
<td >0,14</td>
</tr>
$ sed -r ':k /<tr>/,/<\/tr>/{/<\/tr>/! {N;s/\n/ /;tk}}' file
<tr> <td >441</td> <td >S</td> <td >0,74</td> </tr>
<tr> <td >442</td> <td >S</td> <td >0,14</td> </tr>