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

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

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

решение1

Для преобразования последовательностейболее одного пространствана вкладку, нооставьте отдельные пространства в покое:

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' {} \;

Используйте эту форму для MacOS (или просто для избежания экранирования +в Linux):

sed -E 's/ + /\t/g'

а также другие опции и т. д., которые вам понадобятся из приведенных выше примеров.

решение2

Если ваш персонаж имеет несколько вкладок, вы также можете использовать 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 " "

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

решение3

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

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

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

решение4

Самый простой ответ, использующий только 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 -s ' ' '\t' <<EOF
a b   c
d   e    f
  g h i
EOF
a       b       c
d       e       f
        g       h       i

Связанный контент