Замініть пробіли на вкладки в Linux


98

Як замінити пробіли на вкладки в Linux у даному текстовому файлі?

Відповіді:


168

Використовуйте програму нерозгорнутого (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'').

4
Woah, ніколи не знав розширити / розширити існували. Я намагався зробити все навпаки, а розширення було ідеальним, а не те, щоб возитися з trабо sed.
Ібрагім

4
Для запису, розгорніть / розгорніть стандартні утиліти .
Кодзіро

4
Настільки круто, що це стандарт. Я люблю філософію UNIX . Було б непогано, якби це могло зробити на місці.
Matthew Flaschen

3
Я не думаю, що тут функція
олала

13
Тільки обережно - нерозгортання не перетворить жодного пробілу на вкладку. Якщо вам потрібно наосліп перетворити всі пробіги символів 0x20 на одну вкладку, вам потрібен інший інструмент.
Steve S.

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/… . Подібні деталі синтаксису можна знайти тут (зауважте, що це людина для grep, а не sed): gnu.org/software/grep/manual/grep.html#Basic-vs-Extended .
Віктор Ярема

11

Використання Perl :

perl -p -i -e 's/ /\t/g' file.txt

3
Виникла подібна проблема із заміною послідовних пробілів на одну вкладку. Perl працював, працював лише з додаванням «+» до регулярного виразу.
Тодд,

Хоча, звичайно, я хотів зробити навпаки: перетворити вкладки у два пробіли:perl -p -i -e 's/\t/ /g' *.java
TimP

Чи можу я це зробити рекурсивно?
Аарон Франке,

9

краще команда tr :

tr [:blank:] \\t

Це очистить вивід say, unzip -l , для подальшої обробки grep, cut тощо.

наприклад,

unzip -l some-jars-and-textfiles.zip | tr [:blank:] \\t | cut -f 5 | grep jar

Мені не потрібно використовувати лапки, щоб змусити це працювати:tr [:blank:] \\t
Ömer,

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.
Аркод,

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
Питання про вкладки, це не відповідь.
Метью Прочитав
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.