Différences entre sed sur Mac OSX et d'autres "standard" sed?

J'ai une certaine difficulté à utiliser une réponse fournie sur ce site pour cette question à propos d'une command sed pour replace une ligne vierge par deux autres lignes de contenu et elle a été émise si la command sed sur Mac OS (10.6.7 pour moi ) est différent. Je ne pense pas que c'est, mais je me demandais si d'autres sur ce site pensaient différemment.

Le comportement des utilitaires shell diffère de manière mineure entre les variantes unix. Il existe de nombreuses variantes unix , avec un historique complexe . Il y a des efforts de normalisation tels que le standard POSIX et son sur-set de la spécification UNIX unique . La plupart des systèmes implémentent aujourd'hui POSIX: 2001, également connu sous le nom de Single UNIX Specification version 3 , avec des écarts mineurs et de nombreuses extensions. La spécification Unix unique n'est pas un tutoriel, mais la version 3 est lisible si vous avez déjà une idée de ce que fait une command. Vous pouvez le consulter pour savoir si une fonctionnalité est standard ou une extension d'un système particulier.

Une majorité d'users Unix utilisent Linux et n'ont utilisé aucune autre variante. Linux est livré avec les utilitaires GNU , qui ont souvent de nombreuses extensions à la norme. Vous findez donc beaucoup de code qui fonctionne sous Linux mais pas sur d'autres, car il s'appuie sur ces extensions.

En ce qui concerne sed, consultez la spécification sed Single Unix pour connaître le minimum que chaque système est supposé prendre en charge, la page man de votre système pour ce que votre implémentation prend en charge et le manuel GNU sed pour ce que la plupart des users utilisent.

L'une des extensions non standard de GNU sed prend en charge plusieurs commands exécutées set. Par exemple, ce programme GNU sed imprime toutes les lignes contenant un a , mais change b en c abord:

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

{ et } sont en fait des commands séparées, donc pour une portabilité totale, vous devez les spécifier sur des lignes séparées (dans un file) ou dans des arguments -e distincts (sur la command line). L'absence d'un séparateur de commands après { et l'utilisation de ; en tant que séparateur de commands sont des extensions communes. L'absence d'un séparateur de commands avant } est une extension less courante. Ceci est conforme à la norme:

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

Ceci est non standard mais communément accepté:

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

Une autre extension non standard mais commune est l'utilisation de \n pour désigner une nouvelle ligne dans un text de rlocation (l'utilisation dans une expression rationnelle est standard). La méthode portable consiste à inclure backslash-newline dans le script sed. Une autre extension commune est \+ , \? et \| en regexps pour signifier un ou plusieurs, au plus un et l'alternance; les expressions régulières de base portables n'en ont aucun. Par exemple, la première command est une manière non portable de replace des séquences contiguës d'espaces par une nouvelle ligne; la deuxième command est un équivalent conforme aux normes.

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

OS X est actuellement livré avec un FreeBSD sed de 2005. La plupart des différences ci-dessous s'appliquent également aux autres versions BSD sed.

OS sed utilise -E pour ERE et GNU sed utilise -r . -E est un alias de -r dans GNU sed (ajouté en 4.2, non documenté jusqu'à 4.3). Les nouvelles versions de FreeBSD et NetBSD sed supportent à la fois -E et -r . OpenBSD sed ne supporte que -E .

-i '' fonctionne avec sed mais non avec GNU sed d'OS X. -i fonctionne avec GNU sed, les versions récentes de NetBSD, OpenBSD sed , mais pas OS sed. -i -e fonctionne avec les deux, mais dans le cas de FreeBSD sed fait une sauvegarde du file original avec -e ajouté au nom du file (et vous ne devez pas passer plus d'une expression à sed ).

GNU sed interprète les séquences d'échappement comme \t , \n , \001 , \x01 , \w et \b . OS X sed et POSIX sed interprétent seulement \n (mais pas dans la partie de rlocation de s ).

GNU sed interprète \| , \+ et \? dans BRE, mais sed et POSIX sed de OS X ne le font pas. \( , \) , \{ , et \} sont POSIX BRE.

GNU sed permet d'omettre ; ou une nouvelle ligne avant } mais le sed de OS X ne le fait pas.

i (insert), a (append) et c (change) doivent être suivis d'une barre oblique inversée et d'une nouvelle ligne dans sed et POSIX sed de OS X mais pas dans GNU sed. GNU sed ajoute une nouvelle ligne manquante après le text inséré par i , a ou c mais sed ne l'est pas. Par exemple sed 1ia est une alternative GNU à sed $'1i\\\na\n' .

Par exemple, printf a|sed -np ajoute une nouvelle ligne dans sed mais pas dans GNU sed.

Le sed de OS X ne prend pas en charge les modificateurs I (insensibles à la casse) ou M (multiligne). Les versions plus récentes de FreeBSD sed supportent I

Le sed de OS X ne supporte pas -s ( --separate ), -u ( --unbuffered ), ou -z ( --null-data ).

Une option BSD qui n'est pas prise en charge par GNU sed est -a , ce qui rend w append à un file au lieu de tronquer un file.

Exemples de commands sed de GNU qui ne fonctionnent pas avec sed de 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 

La meilleure façon d'avoir le même script sur Linux et Mac est de:

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