Як замінити кілька пробілів на одній вкладці


27

У мене є текстові файли, які містять стовпчики, розділені різною кількістю пробілів, але замість цього мені потрібна одна вкладка як роздільник. Чи можна це робити в Баші?


Дякую за чудовий вклад, але у мене є кілька пробілів всередині стовпця, тому мені доводиться уникати вкладки єдиного пробілу. вибачте за це, єінформація.
user_unknown

Відповіді:


31

Щоб конвертувати послідовності з декількох пробілів у вкладку, а окремі пробіли залишити в спокої :

sed 's/ \+ /\t/g' inputfile > outputfile

Для цього для декількох файлів:

for inputfile in *
do
    sed 's/ \+ /\t/g' "$inputfile" > tmpfile && mv tmpfile "$inputfile"
done

або

for inputfile in *
do
    sed -i.bak 's/ \+ /\t/g' "$inputfile"
done

або

find . -type f -exec sed -i.bak 's/ \+ /\t/g' {} \;

sed: -e expression #1, char 1: unknown command: `.'
Аарон Франке

@AaronFranke: Яку команду ви спробували? Жоден із прикладів моєї відповіді не повинен спричинити цю помилку.
Призупинено до подальшого повідомлення.

Вибачте, я повинен був уточнити. Той, findщо внизу.
Аарон Франке

@AaronFranke: GNU sedне любить місця перед розширенням резервного копіювання. Я відредагував свою відповідь. Дякуємо за звіт.
Призупинено до подальшого повідомлення.

7

Якщо у вашого персонажа кілька вкладок, ви також можете використовувати tr -s:

-s, --squeeze-repeats   replace each input sequence of a repeated character
                        that is listed in SET1 with a single occurrence

Наприклад:

my_file.txt | tr -s " "

Усі білі простори стануть цілими.


Це не те, що просять ОП.
RonJohn

5

Можна sedзамінити ряд пробілів на вкладку .:

Приклад заміни одного або декількох пробілів однією вкладкою:

cat spaced-file | sed 's/ \+/\t/g' > tabbed-file

ОП заявила, що кількість пробілів є змінною , тому я не думаю, що це рішення спрацює.
Мікель

@Mikel. На жаль Дякуємо, що вказали на це. Я відредагував публікацію, щоб дозволити збіг для змінних пробілів.
IvanGoneKrazy

Тут найкорисніша відповідь.
Луїш де Соуза

3

Найпростіша відповідь, що використовується лише bash:

while read -r col1 col2 col3 ...; do
    echo -e "$col1\t$col2\t$col3..."
done <file

Якщо є змінна кількість стовпців, ви можете це зробити, але це буде працювати лише в bash, а не sh:

while read -r -a cols; do
    (
        IFS=$'\t'
        echo "${cols[*]}"
    )
done <file

напр

while read -r -a cols; do
    (
        IFS=$'\t'
        echo "${cols[*]}"
    )
done <<EOF
a b   c
d   e    f
  g h i
EOF

виробляє:

a   b   c
d   e   f
g   h   i

(Між кожним є вкладка, але важко помітити, коли я вставляю її сюди)

Ви також можете це зробити, використовуючи sedабо tr, але зауважте, що обробка заготовок на старті дає різні результати.

sed:

$ sed 's/  */\t/g' << EOF
a b   c
d   e    f
  g h i
EOF
a       b       c
d       e       f
        g       h       i

tr:

$ tr -s ' ' '\t' <<EOF
a b   c
d   e    f
  g h i
EOF
a       b       c
d       e       f
        g       h       i


2

Спробуйте такий сценарій SED:

 sed 's/  */<TAB>/g' <spaces-file > tabs-file

Де <TAB> натискає клавішу TAB.


0

Це дуже просте рішення:

    sed -E 's/\s+/\t/g' your_file > new_file

sed в основному працює таким чином (sed 's / old_pattern / new_pattern / g'). У цьому випадку старий шаблон є "\ s +", що означає знаходити простір "s" один чи більше разів "+", а зворотний косий рядок "\" інтерпретувати це як регулярний вираз.
Новим шаблоном є вкладка "\ t", яка записується у форматі регулярного вираження, а "g" застосовується заміна до всіх рядків "глобально".


1
Привіт і ласкаво просимо до суперпользователя. Ви повинні витратити час на пояснення свого рішення. Для тих, хто не знайомий із системами * nix, sed та регулярними виразами, це виглядає як купа дивних символів.
Могет
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.