J'apprends awk
et j'aimerais savoir s'il existe une option pour écrire les modifications dans le fichier, comme pour sed
où j'utiliserais -i
option pour enregistrer les modifications dans un fichier.
Je comprends que je pourrais utiliser la redirection pour écrire les modifications. Cependant, y a-t-il une option dans awk
pour le faire?
Au plus tard GNU Awk (depuis 4.1.0 publié ), il a l'option de édition du fichier "inplace" :
[...] L'extension "inplace", construite à l'aide de la nouvelle installation, peut être utilisée pour simuler 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
Sauf si vous avez GNU awk 4.1.0 ou version ultérieure ...
Vous n'aurez pas une telle option comme sed's -i
option alors faites plutôt:
$ awk '{print $0}' file > tmp && mv tmp file
Noter la -i
n'est pas magique, il crée également un fichier temporaire sed
le gère simplement pour vous.
À partir de GNU awk 4.1.0 ...
GNU awk
a ajouté cette fonctionnalité dans la version 4.1.0 (publiée le 10/05/2013). Ce n'est pas aussi simple que de simplement donner le -i
option décrite dans les notes publiées:
La nouvelle option -i (de xgawk) est utilisée pour charger les fichiers de la bibliothèque awk. Cela diffère de -f en ce que le premier argument sans option est traité comme un script.
Vous devez utiliser le paquetage inplace.awk
inclure un fichier pour appeler 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, la mise en oeuvre n'est pas très bizarre car le pouvoir vient de la concision du langage et du -i inplace
est 8 caractères trop long i.m.o.
Voici un lien vers le manuel pour le mot officiel.
Cela ne peut pas marcher:
someprocess < file > file
Le shell effectue les redirections avant que ne confie le contrôle à un processus ( redirections ). Le >
_ 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’ya aucune donnée à lire.
Une alternative consiste à 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 souhaitez modifier à la place.
sponge
absorbe entièrement l'entrée avant de l'enregistrer dans le fichier.
juste un petit bidouillage qui fonctionne
echo "$(awk '{awk code}' file)" > file
suivre 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
a lieu et est exécutée après la commande awk
en raison de la commande |
.
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