J'ai trouvé quelques façons de passer des variables de shell externes à un awk
script, mais je suis confus à propos de '
et "
.
Tout d'abord, j'ai essayé avec un script shell:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
Ensuite, j'ai essayé awk:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
Pourquoi est la différence?
Enfin, j'ai essayé ceci:
$ awk 'BEGIN{print " '$v' "}'
$ 123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1: ^ unexpected newline or end of string
Je suis confus à ce sujet.
/var/
. À la place, utilisez le tilde:awk -v var="$var" '$0 ~ var'
Réponses:
Utilisation
-v
(La meilleure façon, la plus portable)Utilisez l'
-v
option: (PS utilisez un espace après-v
ou ce sera moins portable. Par exemple,awk -v var=
pasawk -vvar=
)Cela devrait être compatible avec la plupart
awk
, et la variable est également disponible dans leBEGIN
bloc:Si vous avez plusieurs variables:
Attention . Comme l'écrit Ed Morton, les séquences d'échappement seront interprétées et
\t
deviennent donc un réeltab
et non\t
si c'est ce que vous recherchez. Peut être résolu en l'utilisantENVIRON[]
ou en y accédant viaARGV[]
PS Si vous aimez trois barres verticales comme séparateur
|||
, il ne peut pas être échappé, alors utilisez-F"[|][|][|]"
Variable après bloc de code
Ici, nous obtenons la variable après le
awk
code. Cela fonctionnera bien tant que vous n'avez pas besoin de la variable dans leBEGIN
bloc:awk '{print a,b,$0}' a="$var1" b="$var2" file
FS
pour chaque fichier.awk 'some code' FS=',' file1.txt FS=';' file2.ext
BEGIN
bloc:echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Here-string
Une variable peut également être ajoutée à l'
awk
utilisation d'une chaîne ici à partir de shells qui les prennent en charge (y compris Bash):C'est la même chose que:
PS cela traite la variable comme une entrée de fichier.
ENVIRON
contributionComme TrueY l'écrit, vous pouvez utiliser
ENVIRON
pour imprimer les variables d'environnement . En définissant une variable avant d'exécuter AWK, vous pouvez l'imprimer comme ceci:ARGV
contributionComme l'écrit Steven Penny, vous pouvez utiliser
ARGV
pour obtenir les données dans awk:Pour obtenir les données dans le code lui-même, pas seulement le début:
Variable dans le code: UTILISER AVEC ATTENTION
Vous pouvez utiliser une variable dans le
awk
code, mais c'est compliqué et difficile à lire, et comme leCharles Duffy
souligne, cette version peut également être victime d'une injection de code. Si quelqu'un ajoute de mauvaises choses à la variable, elle sera exécutée dans le cadre duawk
code.Cela fonctionne en extrayant la variable dans le code, elle en fait donc partie.
Si vous voulez faire un
awk
qui change dynamiquement avec l'utilisation de variables, vous pouvez le faire de cette façon, mais NE l'utilisez PAS pour des variables normales.Voici un exemple d'injection de code:
Vous pouvez ajouter de nombreuses commandes de
awk
cette façon. Même le faire planter avec des commandes non valides.Informaitons supplémentaires:
Utilisation de guillemets doubles
Il est toujours bon de doubler la variable de citation.
"$variable"
Sinon, plusieurs lignes seront ajoutées sous la forme d'une longue ligne unique.
Exemple:
Autres erreurs que vous pouvez obtenir sans guillemet double:
Et avec un guillemet simple, il n'augmente pas la valeur de la variable:
Plus d'informations sur AWK et les variables
Lisez cette FAQ .
la source
awk -v repo="$1" -v tag="$2" 'BEGIN {print "repo="repo,"tag="tag}'
. Il verra s'il imprime la variable. Postez votre propre question si vous ne pouvez pas le comprendre.Il semble que le bon vieux
ENVIRON
awkle hachage intégré n'est pas du tout mentionné. Un exemple de son utilisation:la source
-v
ne fonctionne pas lorsque la valeur contient des barres obliques inverses.awk -v x='\c\d' ...
alors il sera utilisé correctement. Mais quandx
est imprimé awk laisse tomber le fameux:awk: warning: escape sequence '\c' treated as plain 'c'
message d'erreur ... Merci!-v
été conçu pour fonctionner afin que vous puissiez l'utiliser\t
dans la variable et la faire correspondre à un onglet littéral dans les données, par exemple. Si ce n'est pas le comportement que vous souhaitez, vous n'utilisez pas-v
vous utilisezARGV[]
ouENVIRON[]
.Utilisez l'une de ces options en fonction de la manière dont vous souhaitez gérer les barres obliques inverses dans les variables de shell (
avar
est une variable awk,svar
est une variable de shell):Voir http://cfajohnson.com/shell/cus-faq-2.html#Q24 pour plus de détails et d'autres options. La première méthode ci-dessus est presque toujours votre meilleure option et a la sémantique la plus évidente.
la source
Vous pouvez passer l' option de ligne de commande
-v
avec un nom de variable (v
) et une valeur (=
) de la variable d'environnement ("${v}"
):Ou pour être plus clair (avec beaucoup moins de
v
s):la source
Vous pouvez utiliser ARGV:
Notez que si vous allez continuer dans le corps, vous devrez ajuster l'ARGC:
la source
Je viens de changer la réponse de @ Jotne pour "for loop".
la source
-v
option d'Awk qui a déjà été mentionnée dans de nombreuses réponses existantes. Si vous voulez montrer comment exécuter Awk en boucle, c'est vraiment une question différente.J'ai dû insérer la date au début des lignes d'un fichier journal et c'est fait comme ci-dessous:
Il peut être redirigé vers un autre fichier pour enregistrer
la source