如何使用 Sed 或 perl 删除换行符

如何使用 Sed 或 perl 删除换行符

我有一个巨大的 XML 数据文件,其中包含以下行

<fonts> some of the data </fonts>
<fonts> some of the data </fonts>
<fonts> some of
 the data </fonts>
<fonts> some of the data </fonts>
<fonts> some of the data </fonts>

在这之间我得到了换行符......

$>uname -a
SunOS ******* 5.11 SunOS_Development

答案1

给定一个 XML 文件file.xml

<?xml version="1.0"?>
<root>
  <fonts> some of the data </fonts>
  <fonts> some of the data </fonts>
  <fonts> some of
the data </fonts>
  <fonts> some of the data </fonts>
  <fonts> some of the data </fonts>
</root>

您可以使用 XMLStarlet将normalize-spacesXPath 函数应用于所有节点:fonts

$ xmlstarlet ed -u '//fonts' -x 'normalize-space()' file.xml
<?xml version="1.0"?>
<root>
  <fonts>some of the data</fonts>
  <fonts>some of the data</fonts>
  <fonts>some of the data</fonts>
  <fonts>some of the data</fonts>
  <fonts>some of the data</fonts>
</root>

fonts这会删除侧翼空格,并将所有节点中所有其他类型的空格替换为单个空格。

您是否只想删除换行符fonts节点的数据:

$ xmlstarlet ed -u '//fonts' -x 'translate(., "'$'\n''", "")' file.xml
<?xml version="1.0"?>
<root>
  <fonts> some of the data </fonts>
  <fonts> some of the data </fonts>
  <fonts> some of the data </fonts>
  <fonts> some of the data </fonts>
  <fonts> some of the data </fonts>
</root>

这依赖于您的 shell 扩展$'\n'为文字换行符。

答案2

标准方法是 tr 命令。 XML 可以(并且通常)有极长的行,因为空格实际上并不是 XML 规范的一部分。大多数 Unix 文本命令都是基于行的,很长的行可能会破坏 sed 或 awk 之类的东西(在 Linux 上它们往往会造成巨大的性能损失)。 tr 根本不必关心行,因此它可以很好地处理这些数据。

tr -d '[\r\n]' <inFile > outFile

但是,我担心你的第三条“字体”行,它显示为拆分的。删除该换行符将使文本一起运行,没有任何空格。我知道 Excel .xlsx 文件在单元格中有多行文本的情况下使用换行符(和回车符)。

为什么需要删除空格?它不应该引起任何问题。事实上,我通常通过“xmllint --format”运行 XML,因为这使得它可以在编辑器中查看。它在 Excel 中读回得很好:我打印了漂亮的 XML,将其导入到 Excel,将其写回为长行,并进行了 cksum,结果是相同的。

您可以通过定义 RS = ">" 来避免 awk 中的长行问题; XML 中总是有足够的 > 以避免出现过长的行。然后 awk 在单独的行上看到每个 XML 实体,前面最多有一个文本项。如果有真正的换行符,它们将保留在文本中,因此您会看到第三个输入为

<fonts>
some of\nthe data</fonts>

然后,您可以将每个 NL 或 CR/LF 替换为空格并保留措辞。

如果您需要更详细的代码,请询问。

如果您想知道 Excel 与 XML 有什么关系:Excel 文件(.xlsx、.xlsm 等,而不是 .xls)只是一堆 20 个或更多 XML 文件的 zip。

答案3

我们可以使用 sed 's/\n/ /g' 注意第二个正斜杠后面的空格,上面的表达式用空格替换所有换行符

答案4

我们不能使用sed s'/\n/ /g'

sed 适用于换行分隔文本。当输入的每个项目通过表达式运行时,它已经删除了换行符,因此表达式永远不会匹配。根据定义,您永远无法在一行中间得到换行符。 (已测试。)

在 awk 中,您可以切换 RS '行尾'字符,以便使用其他字符,然后换行符将被保留。或者(在 gawk 中)您可以将 RS 清空,然后整个文件将作为一长行出现。我想不出任何其他标准命令可以让您执行此操作。

要在 sed 中处理换行符,您需要使用保留空间,并根据结束/开始条件的匹配方式(例如,文本、标签跟随文本等)计算如何将其缝合到下一行。

另外,OP 运行在 SunOS 5.11 上,我敢打赌,它的行长度限制为 2048 个字符。所以通用 XML 会破坏它。 Solaris awk 在 6144 (6K) 个字符处中断。

我什至不确定这个文件是否是正确的 XML。 OP 对所需的(丢失,假定已死)标签说不,因此可能还潜伏着其他自制问题。

相关内容