Это должно быть действительно просто, но по какой-то причине это не работает:
sed -i.bak -E 's/\t/ /' file.txt
Вместо замены символов табуляции, это замена t
символов. Я перепробовал все варианты, которые мог придумать, играя с цитатами и т. Д. Я гуглил и нашел всех остальных, использующих довольно похожие выражения, и они, похоже, работают на них.
Это -E
OS X вещь. Я думал, что сбой может быть результатом какой-то странной причуды OS X sed
, поэтому я попробовал это и с Ruby (без -i
), и получил тот же результат:
ruby -pe '$_.gsub!(/\t/," ")' < file.txt > file.new
Я использую Bash 3.2.51 на OS X и iTerm, хотя я не понимаю, насколько это может быть очень актуально. Я не установил никаких странных переменных окружения, хотя могу опубликовать любые, которые, по вашему мнению, могут иметь отношение к делу.
Что может быть не так?
UPDATE : Должно бытья сделал некоторую другую ошибку или опечаткукогда я попробовал версию Ruby, такЖиль указывает, что он делает работу (и я никогда и не было ему рулить меня неправильно!). Я не уверен, что случилось, но я почти уверен, что это была моя ошибка.
источник
\t
вsed
заявлении,CTRL-V<TAB>
где<TAB>
находится клавиша табуляции и клавишаCTRL-V
управления иv
нажата вместе.Ответы:
Синтаксис
\t
символа табуляции в sed не является стандартным. Этот побег является расширением GNU sed . В Интернете вы найдете множество примеров, которые используют его, потому что многие люди используют GNU sed (это реализация sed на не встроенных Linux). Но OS X sed , как и другие * BSD sed, не поддерживает\t
tab и вместо этого обрабатывает\t
как означающий обратную косую черту, за которой следуетt
.Есть много решений, таких как:
Используйте буквенный символ табуляции.
Используйте
tr
илиprintf
для создания символа табуляции.Используйте строковый синтаксис bash, позволяющий экранировать обратную косую черту .
Используйте Perl, Python или Ruby. Размещенный вами фрагмент Ruby работает.
источник
...sed
сценарии (используется через-f
option), буквенные символы табуляции кажутся мне единственной возможностью. При редактировании этого с vim,set noexpandtab
это важно.tr
технику только в том случае, если вы хотите, чтобы ваш коллега ударил вас в лицо, когда они читают ваш сценарий.sed $'s/<regex>/\t/' file.txt
работает для вставки, но,$
кажется, нарушает мой скрипт, когда я пытаюсь включить часть регулярного выражения в мою замену, то естьsed $'s,\(ontology/[0-9]\+\),\t\txxx\1xxx\t\t,'
дает `xxxxxx` с моим ожидаемым значением соответствия, замененным на` `. Есть ли эквивалент\1
при использовании строкового синтаксиса bash? Редактировать: предполагается, что символ Юникода U + 231C находится в середине xxx <U + 231C> xxx.Используйте специфичные для Bash кавычки, которые позволяют вам использовать строки, как в C, так чтобы реальный символ табуляции передавался в sed, а не в escape-последовательности:
источник
работает для меня на OS X и это та же команда, которую я использую на Linux все время.
источник
Как уже отмечалось, не все
sed
реализации поддерживают обозначение\t
в виде горизонтальной табуляции.Вы можете легко добиться замены с помощью:
Это выполняет замену на месте, которая сохраняет ваш исходный файл как «* .old». Perl позволяет использовать альтернативные разделители для классики,
/
делая выражение намного более читабельным (т.е. лишенным синдрома «наклоняющейся зубочистки»).+
Говорит один или более повторений символа табуляции должны быть заменены.g
Модификатор позволяет глобальную замену на протяжении конце каждой строки.источник
Вы также можете использовать
echo
внутриsed
:sed -i "s/$(echo '\t')//g"
источник
echo '\t'
что\t
в некоторых оболочках будет просто выводecho
.Если вы хотите более мощный
sed
(поддерживающий\t
и больше), чем тот, что в OS X, установите GNU sed .источник
sed
проблема в OS X. У вас есть основания полагать, что это проблема? Я был бы счастлив установить GNU sed, если бы у меня была причина полагать, что это решит проблему, но кажется, что я в значительной степени исключил это.ruby -pe '$_.gsub!(/\t/," ")' < file.txt
Если это нормально, требовать
bash
илиzsh
в качестве оболочки, то это самое простое решение, которое я могу придумать:Однако обратите внимание, что
echo
флаги (-n
и-e
) не определены в POSIX, поэтому оболочка, соответствующая POSIX, не требует понимания этих флагов, но многие из них по соображениям совместимости.источник
Я удивлен, что никто не предложил очень простое решение:
sed -i.bak -E 's/\\\t/ /' file.txt
это должно сработать.Вам нужно экранировать escape (отсюда 3 \ s), чтобы sed мог понять, что вы пытаетесь использовать символ \ t в регулярном выражении, когда все подставляется ...
источник
sed
, одного\
достаточно, так как никакого побега не требуется. Проблема в том, что BSDsed
не поддерживает этот синтаксис для вкладок.Это сработало для меня.
sed -e 's / [\ t] / / g'
источник
sed
. Это не то, что использует OP.