logo Debian Debian Debian-France Debian-Facile Debian-fr.org Forum-Debian.fr Debian ? Communautés logo inclusivité

Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 15-10-2024 13:32:11

Tawal
Membre
Distrib. : Debian Stable à jour
Noyau : amd64
(G)UI : Xfce
Inscription : 25-02-2021

[awk/gawk] Deux shebang pour les options de la ligne de commande

Hello,

Il est question de script awk/gawk utilisant un shebang approprié.
Chez moi, awk est un lien vers gawk

Avec le shebang

#!/bin/awk -f

les options passées sur la ligne de commande appelant le script sont traitées comme des options pour awk
Ainsi avec un script du genre :

#!/bin/awk -f
BEGIN {
    for (i=0; i<ARGC; i++) printf("Argument %d : %s\n", i, ARGV[i])
    if (var) printf("La variable vaut %s\n",var)
}


Et en l'appelant comme ceci :

./script_awk -v var="VAR"


Le retour donne

Argument 0 : gawk
La variable vaut VAR


L'option -v a été traitée par awk, on ne la voit pas apparaître dans le tableau des arguments.
Ok, ça peut-être pratique. On peut passer des variables à un programme awk, changer le comportement d'un script …

Mais si mon script awk a ses propres options, il risque d'y avoir des "interférences" avec les options d'awk.
Pour cela, il existe une option d'awk qui permet de ne plus considérer les options de la ligne de commande tout en exécutant le "fichier programme".
C'est un peu comme -f sauf que je vais devoir traiter la ligne de commande dans mon script awk.
Cette option est -E et le shebang devient :

#!/bin/awk -E


Et donc avec le même script, on n'obtient pas le même retour :

#!/bin/awk -E
BEGIN {
    for (i=0; i<ARGC; i++) printf("Argument %d : %s\n", i, ARGV[i])
    if (var) printf("La variable vaut %s\n",var)
}


L'appel :

./script_awk -v var="VAR"


Le retour :

Argument 0 : gawk
Argument 1 : -v
Argument 2 : var=VAR


L'option -v n'a pas été prise en compte par awk.
Je peux donc la traiter dans mon script awk ainsi que son argument. Il existe une fonction getopt pour gérer cela cool

Je vais pouvoir revoir tous mes scripts awk où j'utilise bash juste pour la gestion des options …

Edit:
C'est maintenant sur ma page perso : Script awk - Deux shebang

Edit2:
Il existe une autre solution :
Elle consiste à utiliser l'indicateur de fin d'options '--'.
Ainsi en gardant le shebang habituel avec -f, il est possible de passer des options et à awk et au script.
Un truc du genre :

./script_awk  options_awk_ici  --  options_script_ici  arguments …

Dernière modification par Tawal (15-10-2024 23:52:24)


Comme la science n'est pas infuse, elle se diffuse.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#2 17-10-2024 10:07:10

Tawal
Membre
Distrib. : Debian Stable à jour
Noyau : amd64
(G)UI : Xfce
Inscription : 25-02-2021

Re : [awk/gawk] Deux shebang pour les options de la ligne de commande

Re,

Je poste ici la fonction getopt d'awk/gawk.
Elle est fournie par awk/gawk mais pas dans un état où on peut "l'inclure" dans un script.
Elle est ici : /usr/share/awk/getopt.awk
Elle est donnée avec un petit bout de script de test de la fonction, on ne peut donc pas la précharger dans un script.
Voici la fonction épurée, j'ai juste enlevé le bloc BEGIN.

# getopt.awk --- Do C library getopt(3) function in awk
#                Also supports long options.
#
# Arnold Robbins, arnold@skeeve.com, Public Domain
#
# Initial version: March, 1991
# Revised: May, 1993
# Long options added by Greg Minshall, January 2020

# External variables:
#    Optind -- index in ARGV of first nonoption argument
#    Optarg -- string value of argument to current option
#    Opterr -- if nonzero, print our own diagnostic
#    Optopt -- current option letter

# Returns:
#    -1     at end of options
#    "?"    for unrecognized option
#    <s>    a string representing the current option

# Private Data:
#    _opti  -- index in multiflag option, e.g., -abc
function getopt(argc, argv, options, longopts,    thisopt, i, j)
{
    if (length(options) == 0 && length(longopts) == 0)
        return -1                # no options given

    if (argv[Optind] == "--") {  # all done
        Optind++
        _opti = 0
        return -1

    } else if (argv[Optind] !~ /^-[^:[:space:]]/) {
        _opti = 0
        return -1
    }
    if (argv[Optind] !~ /^--/) {        # if this is a short option
        if (_opti == 0)
            _opti = 2
        thisopt = substr(argv[Optind], _opti, 1)
        Optopt = thisopt
        i = index(options, thisopt)
        if (i == 0) {
            if (_opti >= length(argv[Optind])) {
                Optind++
                _opti = 0
            } else
                _opti++
            return "?"
        }
        if (substr(options, i + 1, 1) == ":") {
            # get option argument
            if (length(substr(argv[Optind], _opti + 1)) > 0)
                Optarg = substr(argv[Optind], _opti + 1)
            else
                Optarg = argv[++Optind]
            _opti = 0
        } else
            Optarg = ""
        if (_opti == 0 || _opti >= length(argv[Optind])) {
            Optind++
            _opti = 0
        } else
            _opti++
        return thisopt

    } else {
        j = index(argv[Optind], "=")
        if (j > 0)
            thisopt = substr(argv[Optind], 3, j - 3)
        else
            thisopt = substr(argv[Optind], 3)

        Optopt = thisopt

        i = match(longopts, "(^|,)" thisopt "($|[,:])")
        if (i == 0) {
            Optind++
            return "?"
        }

        if (substr(longopts, i+1+length(thisopt), 1) == ":") {
            if (j > 0)
                Optarg = substr(argv[Optind], j + 1)
            else
                Optarg = argv[++Optind]
        } else
            Optarg = ""
        Optind++
        return thisopt
    }
}


Ainsi en sauvegardant cette fonction dans un répertoire du AWKPATH,
elle peut être préchargée par un script (pas besoin de la copier/coller).


Comme la science n'est pas infuse, elle se diffuse.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

Pied de page des forums