如何将制表符转换为一个目录的每个文件中的空格(可能递归)?

此外,是否有一种方法来设置每个制表符的空格数?


当前回答

将制表符转换为空格只是在”。Lua " files [tab -> 2个空格]

find . -iname "*.lua" -exec sed -i "s#\t#  #g" '{}' \;

其他回答

我的建议是使用:

find . -name '*.lua' -exec ex '+%s/\t/  /g' -cwq {} \;

评论:

Use in place editing. Keep backups in a VCS. No need to produce *.orig files. It's good practice to diff the result against your last commit to make sure this worked as expected, in any case. sed is a stream editor. Use ex for in place editing. This avoids creating extra temp files and spawning shells for each replacement as in the top answer. WARNING: This messes with all tabs, not only those used for indentation. Also it does not do context aware replacement of tabs. This was sufficient for my use case. But might not be acceptable for you. EDIT: An earlier version of this answer used find|xargs instead of find -exec. As pointed out by @gniourf-gniourf this leads to problems with spaces, quotes and control chars in file names cf. Wheeler.

您可以使用通常可用的pr命令(此处的手册页)。例如,要将制表符转换为四个空格,可以这样做:

pr -t -e=4 file > file.expanded

-t抑制头文件 -e=num将制表符扩展为num个空格

递归转换目录树中的所有文件,跳过二进制文件:

#!/bin/bash
num=4
shopt -s globstar nullglob
for f in **/*; do
  [[ -f "$f" ]]   || continue # skip if not a regular file
  ! grep -qI "$f" && continue # skip binary files
  pr -t -e=$num "$f" > "$f.expanded.$$" && mv "$f.expanded.$$" "$f"
done

跳过二进制文件的逻辑来自这篇文章。

注意:

在git或svn repo中这样做可能是危险的 如果您的代码文件在字符串字面值中嵌入了空白制表符,那么这不是正确的解决方案

没有人提到rpl?使用rpl可以替换任何字符串。 要将制表符转换为空格,

rpl -R -e "\t" "    "  .

非常简单。

简单地用sed替换是可以的,但不是最好的解决方案。如果制表符之间有“额外的”空格,替换后它们仍然在那里,因此页边距将是粗糙的。在行中间展开的制表符也不能正常工作。在bash中,我们可以说相反

find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;

将展开应用到当前目录树中的每个Java文件。如果目标是其他文件类型,则删除/替换name参数。正如其中一条评论提到的,在删除name或使用弱通配符时要非常小心。你可以很容易地破坏存储库和其他隐藏的文件。这就是为什么最初的答案是这样的:

在尝试这样做之前,您应该始终对树进行备份,以防出现错误。

你可以使用vim:

find -type f \( -name '*.css' -o -name '*.html' -o -name '*.js' -o -name '*.php' \) -execdir vim -c retab -c wq {} \;

正如Carpetsmoker所说,它将根据你的vim设置重新标签。文件中的modeline(如果有的话)。此外,它不仅将替换行首的制表符。这通常不是你想要的。例如,你可能有文字,包含制表符。