在 bash 中,如何用 null 替换空行,反之亦然?

在 bash 中,如何用 null 替换空行,反之亦然?

如何在 bash 中用\n\n\0字符替换两个换行符,反之亦然?

我发现td可以将单个换行符替换为空,但不能替换两个连续的换行符。我试过了sed,但似乎不可能。sed似乎是“基于行”的,不喜欢弄乱换行符。

我之所以想这样做,是为了能够对使用 分隔空行的记录文件进行排序sort -z。例如,给定一个文件

record b
foo bar

record a
zee bee
dee da

我想将该文件导入到一个转换中,用 null 替换空白行,然后导入sort -z,再用空白行替换 null,最后将其吐出

record a
zee bee
dee da

record b
foo bar

答案1

初步说明

标题询问你尝试的解决方案;你在问题主体中描述了真正的问题。比较XY问题。这个答案并不完全是“用 null 替换空行,反之亦然”,所以它没有解决标题问题。它在正确的位置注入 null 字节,然后删除它们(因为我认为这更容易),这样它就解决了正文问题。


解决方案

让我们调整一下我的另一个答案:按字母顺序对行包进行排序。您的问题几乎与我回答的问题重复。

在那里,每条记录都以类似这样的标题开头[ProfileX]。在您的例子中,我们可以说一个空行是这样的标题,但第一个记录却没有它。要使用链接解决方案,我们需要事先添加第一个标题,并在末尾删除第一个标题。

sed -e '1 s/^/\n/' -e '1 ! s/^$/\x00/' | sort -z | tr -d '\0' | sed -e '1 d'
#   ^^^^^^^^^^^^^^                                                           add missing header
#                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                apply the other answer (adjusted)
#                                                               ^^^^^^^^^^^^ remove excessive header

如果不进行此修改,则输入中的第一个记录将出现在输出中,前面没有任何空行;除非它是输出中的第一个记录,否则这将是一个问题。并且输出中的第一个记录将在其前面有其标题(如果有);除非它是输入中的第一个记录(没有标题的记录),否则这将是一个问题。

答案2

您无需费心使用 0 作为分隔符。让我们改用 255(十六进制 FF):

#!/bin/bash

ORIGINAL=/path/to/yourfile.txt
SORTED=${ORIGINAL}.sorted
FF=$'\xff'

while read LINE ;do
  if [ "$LINE" = "" ] ;then
    echo
  else 
    echo -n $LINE$FF
  fi
done <$ORIGINAL | sort | tr $FF '\n' >$SORTED

结果:

record a
zee bee
dee da

record b
foo bar

注意:以上假设您的行尾是 Linux (LF),而不是 Windows (CR+LF) 或 Mac (CR)。如果您希望它适用于任何类型的行尾,那么我们必须稍微修改一下脚本。

相关内容