Проблема с регулярным выражением Sed на Mac, отлично работает на Linux

Это отлично работает на Linux (Debian):

sed -e 's,^[ \t]*psd\(.*\)\;,,' 

На mac, я считаю, что я должен использовать флаг -E вместо -E:

sed -E 's,^[ \t]*psd\(.*\)\;,,'

но регулярное выражение не совпадает и, следовательно, не удаляет строки, которые я хочу.

Любые советы о том, как это решить?

Пример ввода:

apa
bepa
    psd(cepa);
depa psd(epa);
  psd(fepa gepa hepa);

Для этого входа ожидаемый результат:

apa
bepa
depa psd(epa);

Ответ 1

Флаг -E означает использование расширенных регулярных выражений. Вы должны просто использовать -E, как в Linux. sed в Mac OS X основан на BSD sed, поэтому не имеет расширений GNU.

После копирования ввода образца:

[~ 507] pbpaste | sed -e 's,^[[:space:]]*psd\(.*\);,,'
apa
bepa

depa psd(epa);

Ответ 2

'\t' не является стандартным в 'sed', это расширение GNU.

Чтобы соответствовать 'tab', вам нужно поместить реальный 'tab' в script. Это легко в файле, сложнее в оболочке.

Такая же проблема может возникнуть в AIX, Solaris и HP-UX или других UNIX.

Ответ 3

В качестве альтернативы вы можете использовать версию sed для GNU вместо реализации, предоставляемой Mac OSX.

Порт Mac предоставляет для него порт sudo port install gsed. После его установки вы можете использовать gsed вместо sed.

Ответ 4

В дополнение к приведенным выше ответам вы можете использовать полезный (но зависящий от оболочки) трюк. В bash используйте $'\t', чтобы ввести буквенный символ табуляции. На моем Mac работает следующее:

sed -e 's,^[ '$'\t''*psd\(.*\);,,'

Обратите внимание, как теперь все выражение sed состоит из трех конкатенированных строк.

Этот трюк может быть полезен, если вам нужен специальный символ табуляции, без соответствия другим пробелам (т.е. когда [[:blank:]] будет слишком инклюзивным). Для вышеизложенного флаг -e не является существенным.

Ответ 5

Я проверил этот пример ввода на моей машине и столкнулся с проблемой, когда в третьей строке был символ табуляции с начала строки, а regexp ^[ \t]*psd\(.*\)\; не соответствовал ему. Это может быть передано классом символов sed [[:blank:]], равным комбинации пространства и символа табуляции. Поэтому вы можете попробовать следующее:

sed -E 's,^[[:blank:]]*psd\(.*\)\;,,' demo.txt

это приведет к следующему выводу:

apa
bepa

depa psd(epa);

но он сохраняет пустые строки в результате. Чтобы получить точный результат, как вы ожидали, я использовал следующее:

sed -n '/^[[:blank:]]*psd\(.*\)\;/!p' demo.txt

результат:

apa
bepa
depa psd(epa);

это просто обратный вывод совпадающего шаблона (!p).

EDIT: Чтобы соответствовать символам табуляции в regexp в sed (macosx), вы также можете попробовать рекомендации от Как я могу вставить символ табуляции с sed в ОС X?