我有一堆文本文件,其中一些包含空行,即仅包含换行符,或者可能的空格后跟换行符。我使用find
命令定位文件。
- 示例文件
#Title 1 12345678 1234 #Title 2 12345678 1234 12345678 1234
- 预期产出
#Title 1 12345678 1234 #Title 2 12345678 1234 12345678 1234
我想删除所有这些空行。我在 Debian Linux Stretch 上使用以下命令进行了尝试:
cat "/path/to/file" | sed '/^\s*$/d' | sponge "/path/to/file";
例如,某些文件有 4 个或更多尾随空行,但上述命令仅删除了除一个尾随空行之外的所有文件。
我怎样才能删除最后一个尾随空行?如前所述:如果文件中还有任何空行,那么这些也应该被删除。
我试图在文件之间获得一些一致性,因为文件存储在 BASH 变量中的排序数组中。然后循环文件并删除所有空行和尾随空行,而某些文件已经没有空行或任何尾随空行。
如果我正确理解您的问题,您想从文本文件中删除(真正或视觉上的)空行。这可以很容易地使用
awk
.对于单个文件,您可以调用
这将只打印行上至少有一个“非空白”字符的文件。这背后的想法是
awk
默认情况下将输入行拆分为“空白”处的“字段”,即空格和制表符的连续运行。但是,如果一行仅包含此类字符,则内部存储在自动变量中的字段数NF
将被识别为“零”。上面的(相当短的)程序强加了NF
必须为非零的条件才能打印当前行。这有效地删除了真正或“视觉上”的空行。由于
awk
默认情况下不会执行内联编辑,您可能不得不求助于将输出重定向到临时文件然后重命名,或者使用理解-i inplace
扩展的足够新的实现:这是另一种可移植的方法,它只包含包含空格以外的内容的行:
您也可以对其他命令使用相同的方法:
写入与源相同的文件是一个相当标准的过程。一些命令使用
-i
(或等效的)来指示就地编辑,但实际上它们实际上写入临时文件,然后用临时文件覆盖原始文件:file
如果没有来自其他地方的硬链接,那效果很好。为了满足这种情况,您需要一个副本:不幸的是,我只能在 macOS 上重现您的问题,其中
sed
理解\s
为s
. 因此,该模式^\s*$
将匹配由零个或多个s
字符组成的任何行。这包括空行,但不包括仅包含类似空格字符的行。删除空行或仅包含空格或制表符的可移植方法是
这用于
grep
仅提取不匹配的行[[:blank:]]*
。该[[:blank:]]*
模式匹配零个或多个空格或制表符。如果你想匹配更多类似空格的字符(包括回车和垂直制表符),请[[:space:]]*
改用。强制模式匹配完整行的-x
选项grep
(就像您使用^
and锚定了表达式一样$
)。您可以将 替换
\s
为[[:space:]]
。此外,大多数sed
版本都有一个-i
标志,表示就地编辑文件。所以这个命令应该工作:在使用 GNU 工具的系统上进行测试;这里,
%
是 shell 提示符,而$
行尾标记由cat -A
:结果文件的末尾没有空行。
一些编辑器允许将光标移动到最后一行下方以更容易在末尾添加新行这一事实与该 sed 命令如何删除明显空的行无关。
(而不是带有 的管道
sponge
,您可以只使用sed -i '/^\s*$/d' file.txt
,但您可能应该使用[[:space:]]*
而不是\s*
更广泛支持的管道。)你可以使用:
它将报告包含至少一个图形字符的行,因此不包括空行或仅包含空白字符、控制字符、未知/未定义/无效字符的行。