178 votes

Sauvegarder les modifications en place avec awk

J'apprends awk et j'aimerais savoir s'il existe une option permettant d'écrire les modifications dans le fichier, similaire à sed où j'utiliserais -i pour enregistrer les modifications dans un fichier.

Je comprends que je pourrais utiliser la redirection pour écrire les changements. Cependant, existe-t-il une option dans awk pour faire ça ?

187voto

lind Points 329

Dans GNU Awk 4.1.0 (version 2013) et ultérieures, il offre l'option suivante "édition de fichiers "in situ :

[...] L'extension "inplace", construite à l'aide de la nouvelle fonction, peut être utilisée pour simuler le programme GNU " sed -i " fonctionnalité. [...]

Exemple d'utilisation :

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 file2 file3

Pour conserver la sauvegarde :

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") }
> { print }' file1 file2 file3

172voto

iiSeymour Points 34967

A moins que vous n'ayez GNU awk 4.1.0 ou plus...

Vous n'aurez pas une telle option comme sed's -i alors faites-le à la place :

$ awk '{print $0}' file > tmp && mv tmp file

Remarque : le -i n'est pas magique, il crée aussi un fichier temporaire sed s'en occupe pour vous.


A partir de GNU awk 4.1.0...

GNU awk ajout de cette fonctionnalité dans la version 4.1.0 (publié le 10/05/2013) . Ce n'est pas aussi simple que de donner le nom de l'entreprise. -i comme décrit dans les notes de mise à jour :

La nouvelle option -i (de xgawk) est utilisée pour charger les fichiers de la bibliothèque awk. Elle diffère de -f en ce sens que le premier argument sans option est traité comme un script.

Vous devez utiliser l'ensemble inplace.awk pour invoquer l'extension correctement comme ceci :

$ cat file
123 abc
456 def
789 hij

$ gawk -i inplace '{print $1}' file

$ cat file
123
456
789

La variable INPLACE_SUFFIX peut être utilisé pour spécifier l'extension d'un fichier de sauvegarde :

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{print $1}' file

$ cat file
123
456
789

$ cat file.bak
123 abc
456 def
789 hij

Je suis heureux que cette fonctionnalité ait été ajoutée, mais pour moi, l'implémentation n'est pas très awkish, car la puissance vient de la concision du langage et de l'utilisation de l'anglais. -i inplace est trop long de 8 caractères i.m.o .

Voici un lien vers le manuel pour le mot officiel.

28voto

Yuri G. Points 1931

Juste un petit hack qui fonctionne

echo "$(awk '{awk code}' file)" > file

19voto

Codoscope Points 385

Une alternative est d'utiliser sponge :

awk '{print $0}' your_file | sponge your_file

Où vous remplacez '{print $0}' par votre script awk et your_file par le nom du fichier que vous voulez modifier en place.

sponge absorbe entièrement l'entrée avant de l'enregistrer dans le fichier.

17voto

glenn jackman Points 69748

@sudo_O a le droit réponse .

Ça ne peut pas marcher :

someprocess < file > file

Le shell effectue les redirections avant le transfert du contrôle à un processus quelconque ( redirections ). Le site > la redirection tronquera le fichier à une taille nulle ( redirection de la sortie ). Par conséquent, au moment où un processus est lancé et veut lire le fichier, il n'y a pas de données à lire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X