web-dev-qa-db-fra.com

sed: -i ne peut pas être utilisé avec stdin sous Mac OS X

J'utilise un analyseur de bison dans mon projet. Quand j'exécute la commande suivante:

sed -i y.tab.c -e "s/  __attribute__ ((__unused__))$/# ifndef __cplusplus\n  __attribute__ ((__unused__));\n# endif/"

Je reçois cette erreur Sed: -i ne peut pas être utilisé avec stdin

La commande fonctionne très bien sur les machines Linux. J'utilise Mac OS X 10.9. Il jette une erreur uniquement sur mac os x. Je ne suis pas sûr pourquoi. Quelqu'un peut-il aider? 

Merci

20
sarghau

Vous devez mettre le fichier d'entrée en dernier paramètre.

sed -i -e "s/  __attribute__ ((__unused__))$/# ifndef __cplusplus\n  __attribute__ ((__unused__));\n# endif/" y.tab.c
11
Trenin

Le problème est que Mac OS X utilise la version BSD de sed, qui traite l'option -i de manière légèrement différente. La version GNU utilisée sous Linux utilise un argument optionnel avec -i: si présent, sed crée un fichier de sauvegarde dont le nom est composé du fichier d'entrée et de l'argument. Sans argument, sed modifie simplement le fichier d'entrée sans enregistrer de sauvegarde de l'original.

Dans BSD sed, l'argument -i est requis. Pour éviter de faire une sauvegarde, vous devez fournir un argument de longueur nulle, par exemple. sed -i '' y.tab.c ....

Votre commande, qui édite simplement y.tab.c sans sauvegarde sous Linux, tente de sauvegarder un fichier de sauvegarde en utilisant "y.tab.c" comme extension. Mais maintenant, avec aucun autre fichier dans la ligne de commande, sed pense que vous souhaitez modifier l'entrée standard sur place, ce qui n'est pas autorisé.

24
chepner

De la page de manuel sed:

-i extension Modifie les fichiers sur place en sauvegardant les sauvegardes avec l'extension spécifiée. Si une extension de longueur nulle est fournie, aucune sauvegarde ne sera sauvegardée. Il est déconseillé de donner une extension de longueur nulle lorsque vous modifiez des fichiers sur place, car vous risquez une corruption ou un contenu partiel in situ - Où l'espace disque est saturé, etc.

La solution consiste à envoyer une extension de longueur nulle comme ceci:

sed -i '' 's/apples/oranges/' file.txt
8
KunMing Xie

Piggy-backing off l'explication de @ chepner pour une solution rapide et sale:

Installez la version de sed qui effectuera le travail avec brew install gnu-sed, puis remplacez les utilisations de sed dans votre script par gsed.

(La communauté homebrew est au courant des problèmes pouvant découler de l'intégration de Mac OS X et est intégrée de manière inattendue. Elle s'est efforcée de ne pas le faire pour la plupart des commandes de distribution alternative.)

2