GNU/Linux >> Znalost Linux >  >> Linux

Transliterační skript pro linuxové prostředí

Použití 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

Použití:

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

Není to odpověď, jen ukazuje stručnější, idiomatický způsob, jak vyplnit table[] pole z odpovědi @konsolebox, jak je popsáno v souvisejících komentářích:

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

takže mapování starých na nové znaky je jasně ukázáno v tom, že znak v prvním split() je mapován na znak(y) pod ním a pro jakékoli další mapování, které chcete, stačí změnit řetězec(y) v split(), nemění 26-ti explicitní přiřazení k tabulce[].

Můžete dokonce vytvořit obecný skript pro mapování a pouze předat staré a nové řetězce jako proměnné:

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

pak v shellu něco takového:

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

a můžete se chránit před vlastními chybami při vyplňování řetězců, např.:

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

Nebylo by dobré vědět, kdybyste napsal, že b mapuje x a později omylem napsal, že b mapuje y? Výše uvedené je opravdu nejlepší způsob, jak toho dosáhnout, ale samozřejmě vaše volání.

Zde je jedno kompletní řešení, jak je diskutováno v komentářích níže

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
}

Přejmenoval jsem table pole jako map jen proto, že iMHO lépe reprezentuje účel pole.

výše uložte do souboru script.awk a spusťte jej jako awk -f script.awk inputfile


To lze provést poměrně stručně pomocí jednořádkového perlu:

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

nebo ekvivalentně (díky jaypal):

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

%h je hash obsahující znaky (klíče) a jejich substituce (hodnoty). s je substituční příkaz (jako v sed). g modifikátor znamená, že substituce je globální a e znamená, že náhradní díl je vyhodnocen jako výraz. Zachytí každý znak jeden po druhém a nahradí je hodnotou v hash, pokud existuje, jinak zachová původní hodnotu. -p přepínač znamená, že každý řádek na vstupu se automaticky vytiskne.

Testování:

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

Linux
  1. Pokyny pro spouštění skriptů Shell pro nováčky

  2. 4 způsoby provádění skriptu Shell v systému UNIX / Linux

  3. Formát data a času pro skript nebo proměnnou prostředí Linux

  1. Jak mohu požádat o zadání Ano/Ne/Zrušit ve skriptu prostředí Linux?

  2. Jak hledat soubory pomocí regulárního výrazu ve skriptu linuxového shellu

  3. Linuxový shell skript pro zálohování databáze

  1. Jak porovnávat čísla a řetězce ve skriptu Linux Shell

  2. 5 nejlepších rozšíření prostředí GNOME pro vaši plochu Linuxu

  3. Šablony s Linuxem ve skriptu Shell?