awk enregistrer les modifications en place

awk et j’aimerais savoir s’il existe une option pour écrire des modifications dans un fichier, similaire à sed où j’utiliserais l’option -i pour enregistrer les modifications apscopes à un fichier.

Je comprends que je pourrais utiliser la redirection pour écrire des modifications. Cependant, y a-t-il une option dans awk pour le faire?

Dans la dernière version de GNU Awk (depuis la version 4.1.0 ), il est possible d’ éditer des fichiers “inplace” :

[…] L’extension “inplace”, construite en utilisant la nouvelle fonctionnalité, peut être utilisée pour simuler la fonctionnalité GNU ” sed -i “. […]

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 

Sauf si vous avez GNU awk 4.1.0 ou version ultérieure …

Vous n’aurez pas une telle option pour l’option -i de sed donc faites plutôt:

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

Note: le -i n’est pas magique, il crée aussi un fichier temporaire sed gère pour vous.


À partir de GNU awk 4.1.0 …

GNU awk ajouté cette fonctionnalité dans la version 4.1.0 (publiée le 10/05/2013) . Ce n’est pas aussi simple que de donner l’option -i comme décrit dans les notes publiées:

La nouvelle option -i (à partir de xgawk) est utilisée pour charger des fichiers de bibliothèque awk. Cela diffère de -f en ce que le premier argument non-option est traité comme un script.

Vous devez utiliser le fichier inclus inplace.awk include pour appeler correctement l’extension comme inplace.awk :

 $ 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ée 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, la mise en œuvre n’est pas très gênante, car la concision du langage est très importante et -i inplace ya 8 caractères à -i inplace .

Voici un lien vers le manuel pour le mot officiel.

@sudo_O a la bonne réponse .

Cela ne peut pas fonctionner:

 someprocess < file > file 

Le shell effectue les redirections avant de transférer le contrôle à someprocess ( redirections ). La redirection va tronquer le fichier à la taille zéro ( redirect 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.

juste un petit hack qui fonctionne

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

Une alternative est d’utiliser une 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 souhaitez modifier en place.

sponge absorbe entièrement l’entrée avant de la sauvegarder dans le fichier.

suivant ne fonctionnera pas

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

cela devrait fonctionner

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

En utilisant tee

  awk '{awk code}' file | tee file 

la commande tee lieu et est exécutée après la fin de la commande awk raison du | .

Si vous voulez une solution awk-only sans créer de fichier temporaire et utilisable avec version! = (Gawk 4.1.0):

 awk '{a[b++]=$0} END {for(c=0;c<=b;c++)print a[c]>ARGV[1]}' file