it-swarm-ru.tech

Отличия sed на Mac OSX и других «стандартных» sed?

У меня возникли некоторые проблемы с использованием ответа, предоставленного на этом сайте для этот вопрос о команде sed для замены пустой строки двумя другими строками содержимого , и он был задан, если команда sed на Mac ОС (10.6.7 для меня) другая. Я не думаю, что это так, но мне было интересно, если другие на этом сайте думали иначе.

67
Peter Grill

Поведение утилит Shell незначительно отличается в разных вариантах Unix. Существует множество вариантов nix , с complexhistory . Существуют усилия по стандартизации , такие как POSIX стандарт и его надстройка единая спецификация UNIX . В настоящее время большинство систем реализуют POSIX: 2001, также известный как Версия спецификации 3 UNIX , с небольшими отклонениями и множеством расширений. Спецификация Single Unix не является учебником, но версия 3 доступна для чтения, если у вас уже есть представление о том, что делает команда. Вы можете обратиться к нему, чтобы узнать, является ли какая-то функция стандартной или расширением конкретной системы.

Большинство пользователей Unix используют Linux и не использовали никаких других вариантов. Linux поставляется с GNU утилитами, которые часто имеют много расширений к стандарту. Таким образом, вы найдете довольно много кода, который работает в Linux, но не в других приложениях, потому что он опирается на эти расширения.

Что касается sed, обратитесь к спецификация sed Single Unix для минимума, который должна поддерживать каждая система, для страница man в вашей системе для поддержки вашей реализации и - GNU sed manual для того, что использует большинство людей.

Одно из нестандартных расширений в GNU sed поддерживает несколько команд, запускаемых вместе. Например, эта GNU программа sed печатает все строки, содержащие a, но сначала изменяет b на c:

sed -ne '/a/ {s/b/c/g; p}'

{ а также } на самом деле являются отдельными командами, поэтому для полной переносимости их необходимо указывать либо в отдельных строках (в файле), либо в отдельных -e аргументы (в командной строке). Отсутствие разделителя команд после { и ​​использование ; в качестве разделителя команд используются общие расширения. Отсутствие разделителя команд перед } является менее распространенным расширением. Это соответствует стандарту:

sed -n -e '/a/ {' -e 's/b/c/g' -e p -e '}'

Это нестандартно, но общепринято:

sed -ne '/a/ { s/b/c/g; p; }'

Другим нестандартным, но распространенным расширением является использование \n означает новую строку в тексте замены s (использование в регулярном выражении является стандартным). Переносимый метод - включить обратную косую черту в новую строку сценария. Другим распространенным расширением является \+, \? а также \| в регулярных выражениях означает один или несколько, самое большее один и чередование; переносимые базовые регулярные выражения не имеют ни одного из них. Например, первая команда - это непереносимый способ замены смежных последовательностей пробелов новой строкой; вторая команда соответствует стандартам.

sed -e 's/ \+/\n/'
sed -e 's/  */\
/'
47

OS X в настоящее время поставляется с ОС FreeBSD 2005 года. Большинство различий ниже также применимы к другим версиям BSD sed.

Sed OS X использует -E для ERE и GNU sed использует -r. -E является псевдонимом для -r in GNU sed (добавлено в 4.2, не документировано до 4.3). Новые версии FreeBSD и NetBSD sed поддерживают как -E, так и -r. OpenBSD sed поддерживает только -E.

-i '' работает с sed OS X, но не GNU sed. -i работает с GNU sed, последние версии NetBSD, OpenBSD sed, но не OS Sed. -i -e работает с обоими, но в случае FreeBSD sed создает резервную копию исходного файла с помощью -e добавляется к имени файла (и вам нужно передать не более одного выражения в sed).

GNU sed интерпретирует escape-последовательности, такие как \t, \n, \001, \x01, \w и ​​\b. OS X sed и POSIX sed интерпретируют только \n (но не в замещающей части s).

GNU sed интерпретирует \|, \+ и ​​\? в BRE, но sed OS X и POSIX sed этого не делают. \(, \), \{ и ​​\} являются POSIX BRE.

GNU sed позволяет пропустить ; или символ новой строки перед }, но OS X не делает этого.

i (вставка), a (добавление) и c (изменение) должны сопровождаться обратной косой чертой и новой строкой в ​​sed OS X и POSIX sed, но не в GNU sed. GNU sed добавляет пропущенную новую строку после текста, вставленного i, a или c, но sed OS X этого не делает. Например, sed 1ia является GNU альтернативой sed $'1i\\\na\n'.

Например, printf a|sed -n p добавляет новую строку в sed OS X, но не в GNU sed.

OS X sed не поддерживает модификаторы I (без учета регистра) или M (многострочные). Более новые версии FreeBSD sed поддерживают I.

Sed OS X не поддерживает -s (--separate), -u (--unbuffered) или -z ( --null-data).

Одна из опций BSD, которая не поддерживается GNU sed - это -a), что позволяет w добавлять к файлу вместо усечения файла.

Примеры команд GNU sed), которые не работают с sed OS X:

sed /pattern/,+2d # like `sed '/pattern/{N;N;d;}'`
sed -n 0~3p # like `awk NR%3==0`
sed /pattern/Q # like `awk '/pattern/{exit}1'` or `sed -n '/pattern/,$!p'`
sed 's/\b./\u&/g' # \u converts the next character to uppercase
sed 's/^./\l&/' # \l converts the next character to lowercase
sed -i '1ecat file_to_prepend' file # e executes a Shell command
sed -n l0 # 0 disables wrapping
69
Lri

Я обнаружил, что лучший способ работы одного и того же скрипта на Linux и Mac:

sed -i.bak -e 's/foo/bar/' -- "${TARGET}" &&
  rm -- "${TARGET}.bak"
6
vikrantt