如何将空格转换为Vim或Linux中的选项卡?

我已经看了几堆关于堆栈溢出的问题,以便如何将空格转换为制表符,而无需查找我需要的内容。 似乎有更多关于如何将制表符转换为空格的问题,但我试图做相反的事情。

Vim我试过了:retab:retab! 没有运气,但我相信这些实际上是从标签到空间反正。

我试图在命令提示符下expandexpand ,没有任何运气。

这里是有问题的文件:

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

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

使用Vim扩展所有领先的空间(比'tabstop'更广泛),你是正确的使用retab但首先确保'expandtab'被重置( :verbose set ts? et?是你的朋友)。 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> :<CU>setlocal lcs=tab:>-,trail:-,eol:$ list! list? <CR> 

1 – 如果你有空格,并希望制表符。

首先,你需要确定有多less个空间将有一个标签。 也就是说,假设你有4个空格,或者8个空格,你可能会想要一个空格为4个空格。 现在有了这些信息,你可以:

 :set ts=4 :set noet :%retab! 

这里有一个问题! 这一系列命令将查找所有文本,而不仅仅是行首的空格。 这意味着这样一个string: "Hey,␣this␣␣␣␣is␣4␣spaces"将成为"Hey,␣this⇥is␣4␣spaces" ,但它不是! 它的一个标签!

为了解决这个小问题,我build议search ,而不是retab

 :%s/^\(^I*\)␣␣␣␣/\1^I/g 

此search将在整个文件中查找以任意数量的选项卡开始,随后是4个空格的任何行,并将其replace为find的任意数量的选项卡加上一个。

这不幸的是,不会立即运行!

首先,文件将有以空格开始的行。 然后search将只转换前4个空格到一个选项卡,并让以下…

你需要重复这个命令。 多less次? 直到你pattern not found一个pattern not found 。 我不能想办法自动化这个过程呢。 但是,如果你这样做:

 `10@:` 

你可能已经完成了。 该命令重复上次search/replace10次。 它不太可能你的程序会有这么多的缩进。 如果有,请重复@@

现在,只是为了完成答案。 我知道你问的是相反的,但你永远不知道什么时候需要撤销事情。

2 – 你有标签,想要空格。

首先,确定您希望将制表符转换为多less个空格。 比方说,你想要每个标签是2个空格。 你然后做:

 :set ts=2 :set et :%retab! 

这将有与string相同的问题。 但是,作为更好的编程风格,不要在string中使用硬标签,你实际上正在做一件好事。 如果你真的需要一个string中的选项卡,使用\t

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

翻译:search4个连续空格(在=字符后面)的每个实例,但是只有当这个点的整个行是空格时(这使用零宽度后视断言\@<= )。 用制表符replace每个find的实例。

Bash片段replace4 -spaces缩进(脚本中有两个{4} ),并在./app文件夹中的所有.py文件中以recursion方式添加选项卡:

 find ./app -iname '*.py' -type f \ -exec awk -i inplace \ '{ match($0, /^(( {4})*)(.*?)$/, arr); gsub(/ {4}/, "\t", arr[1]) }; { print arr[1] arr[3] }' {} \; 

不要在中间或末尾修改4个空格。

在Ubuntu 16.0x和Linux Mint 18下进行了testing

不一致的制表符是Python程序员的地狱诅咒。 我build议他们把它放在他们的vimrc文件中:

 set tabstop=4 set et 

所有标签变成四个空格。 您可以通过键入命令模式将选项卡转换为vi中的空格

 :1, $ s/\t/ /g 

这里有四个空间。 您也可以在视觉模式下select区域,并通过replace来限制其范围。

简单的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()