我在Stack Overflow上看了几个关于如何将空格转换为制表符而没有找到我需要的问题。关于如何将制表符转换为空格,似乎有更多的问题,但我正试图做相反的事情。

在Vim中,我尝试过:retab和:retab!没有运气,但我相信这些实际上是用来从制表符到空格的。

我在命令提示符下尝试了展开和取消展开,但没有任何运气。

以下是该文件:

http://gdata-python-client.googlecode.com/hg-history/a9ed9edefd61a0ba0e18c43e448472051821003a/samples/docs/docs_v3_example.py

如何使用Vim或shell将前导空格转换为制表符?


当前回答

在我的例子中,我有多个空格(字段由一个或多个空格分隔),我想用一个制表符替换它们。下面的人做到了:

:% s/\s\+/\t/g

其他回答

使用Vim扩展所有前导空格(比'tabstop'更宽),使用retab是正确的,但首先确保'expandtab'被重置(:verbose set ts?外星人吗?是你的朋友)。retab需要一个范围,所以我通常指定%表示“整个文件”。

:set tabstop=2      " To match the sample file
:set noexpandtab    " Use tabs, not spaces
:%retab!            " Retabulate the whole file

在做这样的事情之前(特别是Python文件!),我通常设置“list”,这样我就可以看到空白和更改。

我在我的.vimrc中有以下映射:

nnoremap    <F2> :<C-U>setlocal lcs=tab:>-,trail:-,eol:$ list! list? <CR>

简单Python脚本:

import os

SOURCE_ROOT = "ROOT DIRECTORY - WILL CONVERT ALL UNDERNEATH"

for root, dirs, files in os.walk(SOURCE_ROOT):
    for f in files:
        fpath = os.path.join(root,f)
        assert os.path.exists(fpath)
        data = open(fpath, "r").read()
        data = data.replace("    ", "\t")
        outfile = open(fpath, "w")
        outfile.write(data)
        outfile.close()

在我的例子中,我有多个空格(字段由一个或多个空格分隔),我想用一个制表符替换它们。下面的人做到了:

:% s/\s\+/\t/g
:%s/\(^\s*\)\@<=    /\t/g

转换:搜索4个连续空格(在=字符之后)的每个实例,但前提是直到该点的整行都是空格(这使用了零宽度向后查找断言\@<=)。用制表符替换每个找到的实例。

如果您安装了GNU coreutils,请考虑%!不展开—仅优先或对于4个空格制表符,考虑%!Unexpand -t 4——first-only(——first-only是为了防止你意外地用——all调用Unexpand)。

注意,这将只替换指定制表位之前的空格,而不是后面的空格;在vim中,你不会看到任何视觉上的差异,除非你更字面地显示标签;例如,我的~/。vimrc包含集合列表listchars=tab:┈(我怀疑这就是为什么你认为unexpand不起作用)。