GNU/Linux >> Tutoriels Linux >  >> Linux

Script de translittération pour le shell Linux

Utilisation d'Awk :

#!/usr/bin/awk -f
BEGIN {
    FS = OFS = ""
    table["a"] = "e"
    table["x"] = "ch"
    # and so on...
}
{
    for (i = 1; i <= NF; ++i) {
        if ($i in table) {
            $i = table[$i]
        }
    }
}
1

Utilisation :

awk -f script.awk file

Test :

# echo "the quick brown fox jumps over the lazy dog" | awk -f script.awk
the quick brown foch jumps over the lezy dog

Pas une réponse, juste pour montrer une manière plus brève et idiomatique de remplir le table[] tableau de la réponse de @konsolebox comme indiqué dans les commentaires associés :

BEGIN {
    split("a  e b", old)
    split("x ch o", new)
    for (i in old)
        table[old[i]] = new[i]
    FS = OFS = ""
}

ainsi, le mappage des anciens vers les nouveaux caractères est clairement indiqué en ce que le caractère du premier split () est mappé au(x) caractère(s) en dessous et pour tout autre mappage souhaité, il vous suffit de modifier la ou les chaînes dans le split(), ne change pas les affectations explicites de 26 à table[].

Vous pouvez même créer un script général pour effectuer des mappages et simplement transmettre l'ancienne et la nouvelle chaîne en tant que variables :

BEGIN {
    split(o, old)
    split(n, new)
    for (i in old)
        table[old[i]] = new[i]
    FS = OFS = ""
}

puis en shell quelque chose comme ça :

old="a  e b"
new="x ch o"
awk -v o="$old" -v b="$new" -f script.awk file

et vous pouvez vous protéger de vos propres erreurs en remplissant les chaînes, par exemple :

BEGIN {
    numOld = split(o, old)
    numNew = split(n, new)

    if (numOld != numNew) {
        printf "ERROR: #old vals (%d) != #new vals (%d)\n", numOld, numNew | "cat>&1"
        exit 1
    }

    for (i=1; i <= numOld; i++) {
        if (old[i] in table) {
            printf "ERROR: \"%s\" duplicated at position %d in old string\n", old[i], i | "cat>&2"
            exit 1
        }
        if (newvals[new[i]]++) {
            printf "WARNING: \"%s\" duplicated at position %d in new string\n", new[i], i | "cat>&2"
        }
        table[old[i]] = new[i]
    }
}

Ne serait-il pas bon de savoir si vous avez écrit que b correspond à x et que vous avez ensuite écrit par erreur que b correspond à y ? Ce qui précède est vraiment la meilleure façon de le faire, mais votre appel bien sûr.

Voici une solution complète comme discuté dans les commentaires ci-dessous

BEGIN {
    numOld = split("a  e b", old)
    numNew = split("x ch o", new)

    if (numOld != numNew) {
        printf "ERROR: #old vals (%d) != #new vals (%d)\n", numOld, numNew | "cat>&1"
        exit 1
    }

    for (i=1; i <= numOld; i++) {
        if (old[i] in table) {
            printf "ERROR: \"%s\" duplicated at position %d in old string\n", old[i], i | "cat>&2"
            exit 1
        }
        if (newvals[new[i]]++) {
            printf "WARNING: \"%s\" duplicated at position %d in new string\n", new[i], i | "cat>&2"
        }
        map[old[i]] = new[i]
    }

    FS = OFS = ""
}
{
    for (i = 1; i <= NF; ++i) {
        if ($i in map) {
            $i = map[$i]
        }
    }
    print
}

J'ai renommé le table tableau sous la forme map juste parce que iMHO représente mieux le but du tableau.

enregistrer ce qui précède dans un fichier script.awk et exécutez-le en tant que awk -f script.awk inputfile


Cela peut être fait de manière assez concise en utilisant un one-liner Perl :

perl -pe '%h=(a=>"xy",c=>"z"); s/(.)/defined $h{$1} ? $h{$1} : $1/eg'

ou de manière équivalente (merci jaypal):

perl -pe '%h=(a=>"xy",c=>"z"); s|(.)|$h{$1}//=$1|eg'

%h est un hachage contenant les caractères (clés) et leurs substitutions (valeurs). s est la commande de substitution (comme dans sed). Le g modificateur signifie que la substitution est globale et le e signifie que la pièce de rechange est évaluée comme une expression. Il capture chaque caractère un par un et les remplace par la valeur dans le hachage s'il existe, sinon conserve la valeur d'origine. Le -p commutateur signifie que chaque ligne de l'entrée est automatiquement imprimée.

En test :

$ perl -pe '%h=(a=>"xy",c=>"z"); s|(.)|$h{$1}//=$1|eg' <<<"abc"
xybz

Linux
  1. Instructions d'exécution des scripts Shell pour les débutants

  2. 4 façons d'exécuter un script shell sous UNIX / Linux

  3. 2 Scripts Perl de régression de mémoire pour Linux

  4. Comment puis-je demander une entrée Oui/Non/Annuler dans un script shell Linux ?

  5. convention de nommage pour le script shell et le makefile

Comment exécuter une commande / un script Linux Shell en arrière-plan

Top 6 des shells open source pour Linux

Comment stocker une commande Linux en tant que variable dans un script shell

Comment exécuter un script Shell en tant que service SystemD sous Linux

Imprimer le temps d'exécution du script Shell sous Linux

Qu'est-ce que Shebang dans Linux Shell Scripting ?