Вы можете использовать sed (Я использую cat -T
для отображения файла, потому что он показывает вкладки как^I
):
$ cat -T file
^I abc
^I ^Ixde^Inot
$ sed ':x;s|^\( *\)\t|\1 |;tx' file | cat -T
abc
xde^Inot
К сожалению, интерпретация \t
как вкладки является расширением GNU sed и не специфицирована POSIX. Однако вы можете обойти это , используя printf
, как показывает здесь Жиль , и написать:
sed ":x;s|^\( *\)$(printf '\t')|\1 |;tx" file
Что там делает sed?
s|^\( *\)\t|\1 |
Если sed находит табуляцию, за которой следует ноль или более пробелов, привязанных к началу строки, она заменяет табуляцию на 4 пробела. Пара \(\)
ограничивает совпадающую группу (, состоящую из нуля или более предшествующих пробелов ), которая воспроизводится с помощью \1
.
tx
Если была произведена замена, перейдите к метке :x
. В противном случае перейдите к следующей строке.
Чтобы заменить все табуляции перед первым символом пробела, не являющимся -, на 4 пробела, попробуйте:
perl -pe '/^(\s+)/; $k=$1; $k=~s/\t/ /g; s/^\s+/$k/'file > newfile
Скрипт сначала найдет все начальные пробелы (пробелы, табуляции и все остальное )и сохранит их как $k
. Затем он заменяет все табуляции 4 пробелами в $k
и, наконец, заменяет все начальные пробелы текущим значением $k
.
Чтобы ограничиться только пробелами и табуляцией, вы можете:
perl -pe '/^([ \t]+)/; $k=$1; $k=~s/\t/ /g; s/^\s+/$k/'file > newfile
Запустите ваши примеры строк, эти решения дадут:
$ printf '\t xxx\n \txxx\n\t \txxx\n\tx\txx\n' | perl -pe '/^(\s+)/; $k=$1; $k=~s/\t/ /g; s/^\s+/$k/' | od -t a
0000000 sp sp sp sp sp x x x nl sp sp sp sp sp sp sp
0000020 x x x nl sp sp sp sp sp sp sp sp sp x x x
0000040 nl sp sp sp sp x ht x x nl
0000052