Mac OSXのsedと他の「標準」sedの違いは何ですか?

Mac OSXのsedと他の「標準」sedの違いは何ですか?

このサイトで提供されている回答を使用する際にいくつかの問題があります。この質問は、空行を他の2行に置き換えるsedコマンドに関するものです。この問題は、Mac OS(私の場合は10.6.7)でsedコマンドが異なる場合に発生します。私はそうは思いませんが、このサイトの他の人は違うと思いますか?

答え1

OS Xは現在2005年のFreeBSD sedに同梱されています。以下の違いのほとんどは、他のBSD sedバージョンにも適用されます。

OS Xのsedは-EERE用で、GNU sedは-r-EGNU sedのエイリアスです-r(4.2に追加され、4.3までは文書化されていません)。最新バージョンのFreeBSDとNetBSDはsed-E-r。 OpenBSD sedは-E

-i ''OS Xのsedでは機能しますが、GNU sedでは機能しません。-iGNU sed、最新バージョンのNetBSD、およびOpenBSDでは機能しますsedが、OS Xのsedでは機能しません。-i -eどちらも機能しますが、FreeBSDの場合は、sed元のファイルのコピーがファイル名に追加されます-e(そして1つ以上の式を渡す必要がありますsed)。

\sGNU sedは、、、、、、、など\tのエスケープシーケンスを解釈します。OS XのsedおよびPOSIX sedについてのみ説明します(代替セクションでは説明しません)。\n\001\x01\w\b\ns

GNU sedはBREで\|、およびを解釈します\+が、\?OS X sedおよびPOSIX sedはそうではありません。\(、、、\)および\{\}POSIX BREです。

GNU sedは;先行省略または改行を許可します}が、OS Xのsedは許可しません。

iOS XのsedとPOSIX sedでは、(挿入)、a(追加)、およびc(変更)の後にバックスラッシュと改行文字が続きますが、GNU sedではそうではありません。 GNU sedはiaまたは挿入されたテキストの後に欠けている改行を追加しますcが、OS Xのsedはそうではありません。たとえば、sed 1iaGNUを置き換えますsed $'1i\\\na\n'

たとえば、printf a|sed -n pOS Xのsedには改行文字が追加されますが、GNU sedでは追加されません。

IOS X用のsedは、(大文字と小文字の区別)または(複数行)の修飾子をサポートしていませんM。最新バージョンのFreeBSDはsedをサポートしていますI

-sOS Xのsedは(--separate)、-u--unbuffered)、-z()をサポートしていません--null-data

GNU sedがサポートしていないBSDオプションの1つは、ファイルを切り捨てるのではなくファイルに追加する-aことです。w

OS X sedで動作しないGNU sedコマンドの例:

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

答え2

異なるUNIXバリアント間には、シェルユーティリティの動作に微妙な違いがあります。たくさんありますUnix変形、複雑 歴史。持つ標準化タスクそうPOSIX標準とその親セット単一のUNIX仕様。今日、ほとんどのシステムはPOSIX:2001とも呼ばれるPOSIX:2001を実装しています。シングルUNIX仕様バージョン3、わずかな偏差と多くの拡張があります。 Single Unixの仕様はチュートリアルではありませんが、コマンドの目的をすでに知っている場合は、第3版をお読みください。これを参照して、特定の機能が標準であるかシステム固有の拡張であるかを確認できます。

ほとんどのUnixユーザーはLinuxを使用し、他のバリアントは使用しません。 Linuxに付属牛に似た一種の栄養標準への多くの拡張を含むユーティリティです。したがって、多くのコードがLinuxでは実行されますが、これらの拡張に依存するため、他のunicesでは実行されないことがわかります。

sedについては、以下を参照してください。sed シングル Unix 仕様すべてのシステムがサポートする必要がある最小限の場合、システムのマニュアルページあなたの実装は何をサポートしますか?GNU sed マニュアルほとんどの人が使用するもの。

GNU sedの非標準拡張の1つは、複数のコマンドを一緒に実行できるようにすることです。たとえば、次の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スクリプトにバックスラッシュの改行を含めることです。もう1つの一般的な拡張子は、正規表現の1つ以上\+、最大1つ、およびシフトを意味します。\?\|移植可能な基本正規表現これらのうち何もない。たとえば、最初のコマンドは、連続した空白シーケンスを改行に置き換える移植不可能な方法です。 2番目のコマンドは標準に準拠したコマンドです。

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

答え3

LinuxとMacで同じスクリプトを使用する最良の方法は次のとおりです。

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

答え4

もう1つの違いは、UTF-8に設定されたLANGまたはLC_CTYPEを使用してバイナリファイルを処理しようとするとMac/BSD sed発生する可能性があることです。エラーは発生しません。error: illegal byte sequenceGNU sed

Mac / BSDでこのエラーが発生した場合は、次のいずれかの方法を試してください。

LC_CTYPE=C sed ...
LC_ALL=C sed ...
LANG=C sed ...

関連情報