it-roy-ru.com

Как я могу преобразовать пробелы в табуляции в Vim или Linux?

Я просмотрел несколько вопросов о переполнении стека, чтобы узнать, как преобразовать пробелы во вкладки, не найдя того, что мне нужно. Кажется, есть еще вопросы о том, как преобразовать табуляции в пробелы, но я пытаюсь сделать наоборот.

В Vim я безуспешно пробовал :retab и :retab!, но я считаю, что они на самом деле предназначены для перехода от табуляции к пробелам в любом случае.

Я попробовал и expand и unexpand в командной строке без какой-либо удачи.

Вот этот файл:

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

Как я могу конвертировать ведущие пробелы во вкладки, используя Vim или оболочку?

156
cwd

Используя Vim для расширения всех ведущих пробелов (шире, чем 'tabstop' ), вы были правы использовать retab , но сначала убедитесь, что 'expandtab' сброшен (:verbose set ts? et? ваш друг). retab принимает range, поэтому я обычно указываю % для обозначения «весь файл».

: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>
261
Johnsyweb

1 - Если у вас есть пробелы и вы хотите вкладки.

Во-первых, вам нужно решить, сколько пробелов будет иметь одну вкладку. Тем не менее, предположим, что у вас есть строки с ведущими 4 пробелами, или 8 ... Чем вы понимаете, что вы, вероятно, хотите, чтобы табуляция была 4 пробелами. Теперь с этой информацией вы делаете:

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

Здесь есть проблема! Эта последовательность команд будет искать весь ваш текст, а не только пробелы в начале строки. Это означает, что строка типа: "Hey,␣this␣␣␣␣is␣4␣spaces" станет "Hey,␣this⇥is␣4␣spaces", но это не так! это вкладка!.

Чтобы решить эту маленькую проблему, я рекомендую search вместо retab.

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

Этот поиск будет искать во всем файле любые строки, начиная с любого количества вкладок, за которыми следуют 4 пробела, и заменять его на любое количество найденных вкладок плюс одну.

Это, к сожалению, не запустится сразу!

Сначала файл будет иметь строки, начинающиеся с пробелов. Затем поиск преобразует только первые 4 пробела в табуляцию, и позволяет следующее ...

Вам нужно повторить команду. Сколько раз? Пока вы не получите pattern not found. Я пока не могу придумать, как автоматизировать процесс. Но если вы делаете:

`[email protected]:`

Вы, вероятно, сделали. Эта команда повторяет последний поиск/замену 10 раз. Вряд ли в вашей программе будет так много отступов. Если это так, просто повторите еще раз @@.

Теперь просто для завершения ответа. Я знаю, что вы просили об обратном, но никогда не знаете, когда вам нужно что-то отменить.

2 - У вас есть вкладки и хотите пробелы.

Во-первых, решите, во сколько мест вы хотите конвертировать ваши вкладки. Допустим, вы хотите, чтобы каждая вкладка была 2 пробела. Затем вы делаете:

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

Это будет иметь ту же проблему со строками. Но так как это лучший стиль программирования, позволяющий не использовать жесткие вкладки внутри строк, вы на самом деле делаете здесь что-то хорошее. Если вам действительно нужна вкладка внутри строки, используйте \t.

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

Перевод: Поиск для каждого экземпляра 4 последовательных пробелов (после символа =), но только в том случае, если вся строка до этой точки является пробелом (при этом используется обратное утверждение нулевой ширины, \@<=). Замените каждый найденный экземпляр символом табуляции.

11
Simon Zuckerbraun

Изменяет все пробелы на tab:%s/\s/\t/g

3
murat budak

Фрагмент Bash для замены отступа 4 - пробелов (в скрипте два {4}) на вкладки во всех файлах .py в папке ./app (рекурсивно):

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

0
maxkoryukov

В моем случае у меня было несколько пробелов (поля были разделены одним или несколькими пробелами), которые я хотел заменить на вкладку. Следующие сделали это: 

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