8

我有一个代码库,由于尾随空格而使我因冲突而发疯。我想把它清理干净。

我想:

  • 删除所有尾随空格
  • 删除文件末尾的所有换行符
  • 将所有行尾转换为 unix (dos2unix)
  • 将所有前导空格转换为制表符,即将 4 个空格转换为制表符。

  • 忽略 .git 目录。

我在OSX Snow Leopardzsh上。

到目前为止,我有:

sed -i "" 's/[ \t]*$//' **/*(.)

效果很好,但是 sed 在它接触的每个文件的末尾添加了一个新行,这不好。我不认为 sed 可以停止这样做,那么我怎样才能删除这些新行?这里可能需要应用一些 awk 魔法。

(也欢迎完整回答)

4

2 回答 2

6

[编辑:固定空白修剪]
[编辑 #2:从文件末尾去除尾随空白行]

perl -i.bak -pe 'if (defined $x && /\S/) { print $x; $x = ""; } $x .= "\n" x chomp; s/\s*?$//; 1 while s/^(\t*)    /$1\t/; if (eof) { print "\n"; $x = ""; }' **/*(.)

这会从文件中删除尾随的空白行,但在文件末尾仅保留一个\n。大多数工具都期望这一点,并且它不会在大多数编辑器中显示为空白行。但是,如果您确实想删除最后一个\n,只需print "\n";从命令中删除该部分即可。

该命令通过“保存”\n字符来工作,直到看到包含非空白字符的行 - 然后在处理该行之前将它们全部打印出来。

删除.bak以避免创建原始文件的备份(使用风险自负!)

\s*?非贪婪地匹配零个或多个空白字符,包括DOS 换行符语法\r的第一个字符。\r\n在 Perl 中,$匹配在行尾,或者紧接在 final 之前,因此结合非贪婪匹配\n的事实(首先尝试 0 宽度匹配,然后是 1 宽度匹配,依此类推)它会*?正确的事。

1 while s/^(\t*) /$1\t/只是一个循环,它重复替换以任意数量的制表符开头的任何行,然后是 4 个空格,比以前多了一个制表符,直到不再可能。因此,即使某些行已经部分转换为制表符,它也可以工作,前提是所有\t字符都从可被 4 整除的列开始。

之前没见过**/*(.)语法,估计是zsh扩展吧?如果它适用于sed,它将适用于perl

于 2011-02-16T01:56:13.080 回答
0

来自 Mac:

find . -iname '*.swift' -type f -exec sed -i '' 's/[[:space:]]\{1,\}$//' {} \+

swift这将递归地从当前目录中的所有文件中删除所有尾随空格。您可以根据需要更改文件类型。

于 2019-11-19T12:50:53.493 回答