GNU/Linux >> Linux Esercitazione >  >> Linux

Script di traslitterazione per shell linux

Utilizzo di 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

Utilizzo:

awk -f script.awk file

Prova:

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

Non una risposta, solo per mostrare un modo più breve e idiomatico per popolare table[] array dalla risposta di @konsolebox come discusso nei commenti correlati:

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

quindi la mappatura dei caratteri vecchi con quelli nuovi è chiaramente mostrata in quanto il carattere nel primo split() è mappato sui caratteri sotto di esso e per qualsiasi altra mappatura che desideri devi solo cambiare la stringa o le stringhe nel split(), non modificare le assegnazioni esplicite di 26-ish in table[].

Puoi persino creare uno script generale per eseguire le mappature e semplicemente passare le stringhe vecchie e nuove come variabili:

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

quindi nella shell qualcosa di simile a questo:

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

e puoi proteggerti dai tuoi errori nel popolare le stringhe, ad esempio:

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

Non sarebbe utile sapere se hai scritto che b è mappato su x e poi in seguito hai scritto erroneamente che b è mappato su y? Quanto sopra è davvero il modo migliore per farlo, ma la tua chiamata ovviamente.

Ecco una soluzione completa come discusso nei commenti qui sotto

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
}

Ho rinominato il table matrice come map solo perché iMHO rappresenta meglio lo scopo dell'array.

salva quanto sopra in un file script.awk ed eseguilo come awk -f script.awk inputfile


Questo può essere fatto abbastanza concisamente usando un one-liner Perl:

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

o equivalentemente (grazie jaypal):

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

%h è un hash contenente i caratteri (chiavi) e le loro sostituzioni (valori). s è il comando di sostituzione (come in sed). Il g modificatore significa che la sostituzione è globale e e significa che la parte di ricambio viene valutata come un'espressione. Cattura ogni carattere uno per uno e li sostituisce con il valore nell'hash se esiste, altrimenti mantiene il valore originale. Il -p switch significa che ogni riga nell'input viene stampata automaticamente.

Provalo:

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

Linux
  1. Ssh:script di shell per l'accesso a un server Ssh?

  2. Script Shell per spostare i file più vecchi?

  3. 2 Script Perl di regressione della memoria per Linux

  4. Come posso richiedere l'input Sì/No/Annulla in uno script della shell di Linux?

  5. Come cercare i file usando regex nello script della shell linux

Come eseguire il comando / script della shell di Linux in background

Le 6 migliori shell open source per Linux

Come memorizzare un comando Linux come variabile nello script della shell

Come eseguire lo script della shell come servizio SystemD in Linux

Stampa il tempo di esecuzione dello script della shell in Linux

Che cos'è Shebang negli script della shell di Linux?