Поведение утилит оболочки незначительно отличается между вариантами Unix. Существует множество вариантов Unix со сложной историей . Существуют усилия по стандартизации, такие как стандарт POSIX и его надмножество спецификации Single UNIX . В настоящее время большинство систем реализуют POSIX: 2001, также известный как версия 3 спецификации Single UNIX , с небольшими отклонениями и множеством расширений. Спецификация Single Unix не является учебником, но версия 3 доступна для чтения, если у вас уже есть представление о том, что делает команда. Вы можете обратиться к нему, чтобы узнать, является ли какая-то функция стандартной или расширением конкретной системы.
Большинство пользователей Unix используют Linux и не использовали никаких других вариантов. Linux поставляется с утилитами GNU , которые часто имеют множество расширений к стандарту. Таким образом, вы найдете довольно много кода, который работает в Linux, но не в других приложениях, потому что он опирается на эти расширения.
Что касается sed, обратитесь к спецификации sed Single Unix для получения информации о минимуме, который должна поддерживать каждая система, к странице руководства вашей системы о том, что поддерживает ваша реализация, и к руководству по GNU sed, которое использует большинство людей.
Одно из нестандартных расширений в 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/ */\
/'
sed
Сам GNU является совместимым, поскольку он делает вещи, разрешенные (но не обязательные, неуказанные) стандартом. Бывают случаи, когда он не соответствует требованиям, и его использованиеPOSIXLY_CORRECT
в среде может помочь. Как и в случае сs/[\n]//g
этим необходимо удалить обратную реакцию иn
символы, но вместо этого удалить символы новой строки. Или поведениеN
команды в последней строке.sed -ne '/a/ { s/b/c/g; p; }'
стандарт с 2016 года выпуска стандарта. Это всегда было портативно. См. Austingroupbugs.net/view.php?id=944&nbn=7OS X в настоящее время поставляется с операционной системой FreeBSD 2005 года. Большинство различий ниже также применимы к другим версиям BSD sed.
OS X использует sed
-E
для ERE и GNU sed использует-r
.-E
псевдоним для-r
в GNU sed (добавлено в 4.2, не документировано до 4.3). Более новые версии FreeBSD и NetBSD sed поддерживают-E
и-r
. OpenBSD sed поддерживает только-E
.-i ''
работает с OS X sed, но не GNU sed.-i
работает с GNU sed, последними версиями NetBSD, OpenBSDsed
, но не с OS X sed.-i -e
работает с обоими, но в случае FreeBSDsed
делает резервную копию исходного файла с-e
добавлением к имени файла (и вам нужно передать не более одного выраженияsed
).GNU SED интерпретирует управляющие последовательности , как
\t
,\n
,\001
,\x01
,\w
, и\b
. OS X и POSIX sed только интерпретируют\n
(но не в заменеs
).GNU sed интерпретирует
\|
,\+
и\?
в BRE, но OS X sed и POSIX sed не делают.\(
,\)
,\{
, И\}
являются POSIX BRE.GNU sed позволяет пропустить
;
или новую строку раньше,}
а OS X - нет.i
(вставка),a
(добавление) иc
(изменение) должны сопровождаться обратной косой чертой и новой строкой в OSD sed и POSIX sed, но не в GNU sed. GNU СЭД добавляет недостающий символ новой строки после текста , вставленныйi
,a
илиc
но OS X в SED не делает. Например,sed 1ia
GNU альтернативаsed $'1i\\\na\n'
.Например,
printf a|sed -n p
добавляет новую строку в OS X sed, но не в GNU sed.OS X sed не поддерживает
I
(без учета регистра) илиM
(многострочные) модификаторы. Более новые версии поддержки FreeBSD sedI
.OS X sed не поддерживает
-s
(--separate
),-u
(--unbuffered
) или-z
(--null-data
).Одна из опций BSD, которая не поддерживается GNU sed
-a
, заключается вw
добавлении файла вместо его усечения.Примеры команд GNU sed, которые не работают с sed OS X:
источник
-i -e
не работает на OSX. Это-e
как суффикс.-i
всегда требуется суффикс, даже если пустая строка. так-i '' -e
должно работать.-i -e
работает с обоими». в вашем ответе предполагается, что есть кроссплатформенное решение. Видимо нет.Я обнаружил, что лучший способ работы одного и того же скрипта на Linux и Mac:
источник
perl
откуда это-i
.perl -Tpi -e 's/foo/bar/' -- "$TARGET"