GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Transliterationsskript für die Linux-Shell

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

Verwendung:

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

Keine Antwort, nur um eine kürzere, idiomatische Art zu zeigen, den table[] zu füllen Array aus der Antwort von @konsolebox, wie in den zugehörigen Kommentaren besprochen:

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

Die Zuordnung von alten zu neuen Zeichen wird also deutlich, indem das Zeichen im ersten split() den darunter liegenden Zeichen zugeordnet wird, und für jede andere gewünschte Zuordnung müssen Sie nur die Zeichenfolge(n) in ändern split(), nicht 26-ish explizite Zuweisungen an table[].

ändern

Sie können sogar ein allgemeines Skript erstellen, um Zuordnungen vorzunehmen, und einfach die alten und neuen Zeichenfolgen als Variablen übergeben:

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

dann in der Shell so etwas:

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

und Sie können sich vor Ihren eigenen Fehlern beim Füllen der Zeichenfolgen schützen, z. B.:

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

Wäre es nicht gut zu wissen, ob Sie geschrieben haben, dass b auf x abbildet und später fälschlicherweise geschrieben haben, dass b auf y abbildet? Das Obige ist wirklich der beste Weg, dies zu tun, aber Sie müssen natürlich anrufen.

Hier ist eine vollständige Lösung, wie in den Kommentaren unten besprochen

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
}

Ich habe table umbenannt Array als map nur weil iMHO das den Zweck des Arrays besser darstellt.

Speichern Sie das obige in einer Datei script.awk und führen Sie es als awk -f script.awk inputfile aus


Dies kann ganz kurz mit einem Perl-Einzeiler geschehen:

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

oder gleichwertig (danke jaypal):

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

%h ist ein Hash, der die Zeichen (Schlüssel) und ihre Substitutionen (Werte) enthält. s ist der Substitutionsbefehl (wie in sed). Die g Modifikator bedeutet, dass die Substitution global ist und der e bedeutet, dass das Ersatzteil als Ausdruck ausgewertet wird. Es erfasst jedes Zeichen einzeln und ersetzt sie durch den Wert im Hash, falls vorhanden, behält ansonsten den ursprünglichen Wert bei. Die -p Schalter bedeutet, dass jede Zeile in der Eingabe automatisch gedruckt wird.

Testen Sie es aus:

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

Linux
  1. So vergleichen Sie Zahlen und Zeichenfolgen im Linux-Shell-Skript

  2. Ssh – Shell-Skript zum Einloggen in einen SSH-Server?

  3. Shell-Skript zum Verschieben der ältesten Dateien?

  4. Formatieren Sie Datum und Uhrzeit für Linux-Shell-Skript oder -Variable

  5. Templating mit Linux in einem Shell-Skript?

So führen Sie einen Linux-Shell-Befehl / ein Skript im Hintergrund aus

Top 6 Open-Source-Shells für Linux

So speichern Sie einen Linux-Befehl als Variable im Shell-Skript

So führen Sie Shell-Skript als SystemD-Dienst in Linux aus

Ausführungszeit des Shell-Skripts in Linux drucken

Was ist Shebang in Linux Shell Scripting?