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
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