如何在 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)。如果您希望它适用于任何类型的行尾,那么我们必须稍微修改一下脚本。