Как заменить несколько пробелов на одной вкладке

27

У меня есть несколько текстовых файлов, которые содержат несколько столбцов, разделенных различным количеством пробелов, но вместо этого мне нужна одна вкладка в качестве разделителя. Можно ли это сделать в Bash?

неизвестный пользователь
источник
Спасибо за отличный ввод, но у меня есть несколько пробелов внутри столбца, поэтому я должен избегать табуляции одного пробела. извините за это, информация.
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 " "

Все пробелы станут одним.

user597119
источник
Это не то, что требует OP.
RonJohn
5

Вы можете использовать sedдля замены нескольких пробелов на вкладку .:

Пример замены одного или нескольких пробелов одной вкладкой:

cat spaced-file | sed 's/ \+/\t/g' > tabbed-file
IvanGoneKrazy
источник
ОП сказал, что количество пробелов было переменным , поэтому я не думаю, что это решение будет работать.
Микель
@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 '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
Mikel
источник
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 и регулярными выражениями, это выглядит как куча странных символов.
Моггет