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

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


当前回答

从Gene的回答中收集最好的评论,到目前为止最好的解决方案是使用moreutils的海绵。

sudo apt-get install moreutils
# The complete one-liner:
find ./ -iname '*.java' -type f -exec bash -c 'expand -t 4 "$0" | sponge "$0"' {} \;

解释:

./从当前目录递归搜索 -iname是不区分大小写的匹配(对*.java和*.java都适用) Type -f只查找常规文件(没有目录、二进制文件或符号链接) -exec bash -c在子shell中为每个文件名执行以下命令,{} expand -t 4将所有tab扩展为4个空格 海绵吸收标准输入(从扩展)并写入文件(同一文件)*。

注意:*一个简单的文件重定向(> "$0")在这里不能工作,因为它会很快覆盖文件。

优点:保留所有原始文件权限,不使用中间的tmp文件。

其他回答

Git存储库友好方法

git-tab-to-space() (
  d="$(mktemp -d)"
  git grep --cached -Il '' | grep -E "${1:-.}" | \
    xargs -I'{}' bash -c '\
    f="${1}/f" \
    && expand -t 4 "$0" > "$f" && \
    chmod --reference="$0" "$f" && \
    mv "$f" "$0"' \
    '{}' "$d" \
  ;
  rmdir "$d"
)

操作当前目录下的所有文件:

git-tab-to-space

仅作用于C或c++文件:

git-tab-to-space '\.(c|h)(|pp)$'

您可能特别需要这个,因为那些讨厌的makefile需要选项卡。

命令git grep——cached -Il ":

只列出被跟踪的文件,所以.git中没有任何内容 不包括目录、二进制文件(将被损坏)和符号链接(将被转换为常规文件)

如在解释:如何列出所有文本(非二进制)文件在一个git仓库?

chmod——reference保持文件权限不变:https://unix.stackexchange.com/questions/20645/clone-ownership-and-permissions-from-another-file不幸的是,我找不到一个简洁的POSIX替代方案。

如果你的代码库有一个疯狂的想法,允许在字符串中使用功能原始制表符,使用:

expand -i

然后一个接一个地浏览所有非行开头的制表符,你可以列出:是否可能为制表符git grep ?

在Ubuntu 18.04上测试。

我的建议是使用:

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.

使用反斜杠转义sed。

在linux上:

将所有*.txt文件中的所有制表符替换为1个连字符: Sed -i $'s/\t/-/g' *.txt 将所有*.txt文件中的所有制表符替换为1个空格: Sed -i $'s/\t/ /g' *.txt 将所有*.txt文件中的所有制表符替换为4个空格: Sed -i $'s/\t/ /g' *.txt

在mac电脑上:

将所有*.txt文件中的所有制表符替换为4个空格: Sed -i " $'s/\t/ /g' *.txt

将目录下的所有Java文件递归转换为4个空格而不是制表符:

find . -type f -name *.java -exec bash -c 'expand -t 4 {} > /tmp/stuff;mv /tmp/stuff {}' \;

你可以使用vim:

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

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