Замените пробелы вкладками в linux

99

Как мне заменить пробелы табуляцией в Linux в данном текстовом файле?

бизнес
источник

Ответы:

169

Используйте программу Unpand (1)


UNEXPAND(1)                      User Commands                     UNEXPAND(1)

NAME
       unexpand - convert spaces to tabs

SYNOPSIS
       unexpand [OPTION]... [FILE]...

DESCRIPTION
       Convert  blanks in each FILE to tabs, writing to standard output.  With
       no FILE, or when FILE is -, read standard input.

       Mandatory arguments to long options are  mandatory  for  short  options
       too.

       -a, --all
              convert all blanks, instead of just initial blanks

       --first-only
              convert only leading sequences of blanks (overrides -a)

       -t, --tabs=N
              have tabs N characters apart instead of 8 (enables -a)

       -t, --tabs=LIST
              use comma separated LIST of tab positions (enables -a)

       --help display this help and exit

       --version
              output version information and exit
. . .
STANDARDS
       The expand and unexpand utilities conform to IEEE Std 1003.1-2001
       (``POSIX.1'').
DigitalRoss
источник
4
Ого, никогда не знал, что существует возможность расширения / расширения. Я пытался сделать наоборот, и расширение было идеальным, вместо того, чтобы возиться с trили sed.
Ибрагим
4
Для справки, раскрыть / развернуть - стандартные утилиты .
Кодзиро
4
Так здорово, что это стандартные. Мне нравится философия UNIX . Было бы неплохо, если бы это можно было сделать на месте.
Matthew Flaschen
3
Я не думаю, что здесь сработает Unpand ... он только преобразует ведущие пробелы и только с двумя или более пробелами .. см. Здесь: lists.gnu.org/archive/html/bug-textutils/2001-01/msg00025.html
olala
13
Только предупреждение - при раскрытии ни одного пробела в табуляцию не превратится. Если вам нужно вслепую преобразовать все серии символов 0x20 в одну вкладку, вам понадобится другой инструмент.
Стив С.
44

Я думаю, ты можешь попробовать с awk

awk -v OFS="\t" '$1=$1' file1

или SED, если вы предпочитаете

sed 's/[:blank:]+/,/g' thefile.txt > the_modified_copy.txt

или даже тр

tr -s '\t' < thefile.txt | tr '\t' ' ' > the_modified_copy.txt

или упрощенная версия tr-решения, предложенного Сэмом Бисби

tr ' ' \\t < someFile > someFile
Джонатан
источник
4
В вашем примере sed лучшие практики диктуют, что вы используете tr для замены одиночных символов на sed из соображений эффективности / скорости. Кроме того, пример tr намного проще:tr ' ' \\t < someFile > someFile
Сэм Бисби
2
Конечно, tr имеет лучшую производительность, чем sed, но главная причина, по которой я люблю Unix, заключается в том, что есть много способов что-то сделать. Если вы планируете делать эту замену много раз, вы будете искать решение с хорошей производительностью, но если вы собираетесь сделать это только один раз, вы будете искать решение, которое включает команду, которая заставит вас чувствовать себя комфортно.
Джонатан,
2
арг. Мне пришлось использовать метод проб и ошибок, чтобы заставить sed работать. Понятия не имею, почему мне пришлось избегать знака плюса вот так:ls -l | sed "s/ \+/ /g"
Джесс
С awk -v OFS="\t" '$1=$1' file1Я заметил , что если у вас есть начало строки с номером 0 (например 0 1 2), то линия будет пропущена из результата.
Никола Новак
@Jess Вы нашли регулярное выражение "правильный синтаксис по умолчанию". По умолчанию sed обрабатывает одиночный (неэкранированный) знак плюса как простой символ. То же самое и с некоторыми другими символами, такими как '?', ... Более подробную информацию можно найти здесь: gnu.org/software/sed/manual/html_node/… . Подобные сведения о синтаксисе можно найти здесь (обратите внимание, что это man для grep, а не sed): gnu.org/software/grep/manual/grep.html#Basic-vs-Extended .
Виктор Ярема,
12

Используя Perl :

perl -p -i -e 's/ /\t/g' file.txt
Джон Милликин
источник
3
Была аналогичная проблема с заменой последовательных пробелов одной табуляцией. Perl работал только с добавлением "+" к регулярному выражению.
Todd
Хотя, конечно, я хотел сделать наоборот: преобразовать табуляцию в два пробела:perl -p -i -e 's/\t/ /g' *.java
TimP 06
Могу ли я сделать это рекурсивно?
Аарон Франке
Это был единственный вариант, который у меня сработал; Раньше я s/ {4}/преобразовывал отступы из 4 пробелов в табуляции.
CrazyPyro,
10

Лучшая команда tr :

tr [:blank:] \\t

Это очистит вывод, скажем, unzip -l для дальнейшей обработки с помощью grep, cut и т. Д.

например,

unzip -l some-jars-and-textfiles.zip | tr [:blank:] \\t | cut -f 5 | grep jar
Таркин
источник
Мне не нужно использовать кавычки, чтобы заставить его работать:tr [:blank:] \\t
Ömer An
3

Загрузите и запустите следующий скрипт для рекурсивного преобразования программных вкладок в жесткие вкладки в текстовых файлах.

Поместите и выполните сценарий из папки, содержащей простые текстовые файлы.

#!/bin/bash

find . -type f -and -not -path './.git/*' -exec grep -Iq . {} \; -and -print | while read -r file; do {
    echo "Converting... "$file"";
    data=$(unexpand --first-only -t 4 "$file");
    rm "$file";
    echo "$data" > "$file";
}; done;
дака
источник
2

Пример команды для преобразования каждого файла .js в текущем каталоге в табуляцию (преобразуются только ведущие пробелы):

find . -name "*.js" -exec bash -c 'unexpand -t 4 --first-only "$0" > /tmp/totabbuff && mv /tmp/totabbuff "$0"' {} \;
аркод
источник
Проверено в cygwin на windows 7.
arkod
1

Вы также можете использовать astyle. Я нашел это весьма полезным, и у него тоже есть несколько вариантов:

Tab and Bracket Options:
   If  no  indentation  option is set, the default option of 4 spaces will be used. Equivalent to -s4 --indent=spaces=4.  If no brackets option is set, the
   brackets will not be changed.

   --indent=spaces, --indent=spaces=#, -s, -s#
          Indent using # spaces per indent. Between 1 to 20.  Not specifying # will result in a default of 4 spaces per indent.

   --indent=tab, --indent=tab=#, -t, -t#
          Indent using tab characters, assuming that each tab is # spaces long.  Between 1 and 20. Not specifying # will result in a default assumption  of
          4 spaces per tab.`
Анкур Агарвал
источник
0

Если вы говорите о замене всех подряд идущих пробелов в строке табуляцией, тогда tr -s '[:blank:]' '\t'.

[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda
Device         Start
/dev/sda1       2048
/dev/sda2     411648
/dev/sda3    2508800
/dev/sda4   10639360
/dev/sda5   75307008
/dev/sda6   96278528
/dev/sda7  115809778
[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:blank:]' '\t'
Device  Start
/dev/sda1       2048
/dev/sda2       411648
/dev/sda3       2508800
/dev/sda4       10639360
/dev/sda5       75307008
/dev/sda6       96278528
/dev/sda7       115809778

Если вы говорите о замене всего пробела (например, пробела, табуляции, новой строки и т. Д.), Тогда tr -s '[:space:]'.

[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:space:]' '\t'
Device  Start   /dev/sda1       2048    /dev/sda2       411648  /dev/sda3       2508800 /dev/sda4       10639360        /dev/sda5       75307008        /dev/sda6     96278528        /dev/sda7       115809778  

Если вы говорите об исправлении файла, поврежденного вкладкой, используйте expandи, unexpandкак указано в других ответах.

землеройка
источник
0

Используя sed :

T=$(printf "\t")
sed "s/[[:blank:]]\+/$T/g"

или

sed "s/[[:space:]]\+/$T/g"
Тибор
источник
-1

Это заменит последовательные пробелы одним пробелом (но не табуляцией).

tr -s '[:blank:]'

Это заменит последовательные пробелы табуляцией.

tr -s '[:blank:]' '\t'
мел
источник
Фактически, -cон заменяет последовательные символы, не являющиеся пробелами.
wingedsubmariner
1
Вопрос о вкладках, это не ответ.
Мэтью Рид