GNU/Linux >> Tutoriales Linux >  >> Linux

Script de transliteración para shell de linux

Usando 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

Uso:

awk -f script.awk file

Prueba:

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

No es una respuesta, solo para mostrar una forma idiomática más breve de completar el table[] matriz de la respuesta de @konsolebox como se discutió en los comentarios relacionados:

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

por lo tanto, la asignación de caracteres antiguos a nuevos se muestra claramente en que el carácter en la primera división () se asigna a los caracteres debajo de él y para cualquier otra asignación que desee, solo necesita cambiar la(s) cadena(s) en el split(), no cambie las asignaciones explícitas de 26 a table[].

Incluso puede crear una secuencia de comandos general para realizar asignaciones y simplemente pasar las cadenas antiguas y nuevas como variables:

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

luego en shell algo como esto:

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

y puede protegerse de sus propios errores que pueblan las cadenas, por ejemplo:

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

¿No sería bueno saber si escribió que b se corresponde con x y luego escribió por error que b se corresponde con y? Lo anterior realmente es la mejor manera de hacer esto, pero tu decisión, por supuesto.

Aquí hay una solución completa como se discute en los comentarios a continuación

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
}

Cambié el nombre del table matriz como map solo porque iMHO eso representa mejor el propósito de la matriz.

guarde lo anterior en un archivo script.awk y ejecútelo como awk -f script.awk inputfile


Esto se puede hacer de manera bastante concisa usando una sola línea de Perl:

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

o equivalente (gracias jaypal):

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

%h es un hash que contiene los caracteres (claves) y sus sustituciones (valores). s es el comando de sustitución (como en sed). El g modificador significa que la sustitución es global y el e significa que la pieza de repuesto se evalúa como una expresión. Captura cada carácter uno por uno y los sustituye con el valor en el hash si existe, de lo contrario mantiene el valor original. El -p cambiar significa que cada línea en la entrada se imprime automáticamente.

Probarlo:

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

Linux
  1. Cómo comparar números y cadenas en Linux Shell Script

  2. Las 5 mejores extensiones de GNOME Shell para su escritorio Linux

  3. Ssh:¿script de shell para iniciar sesión en un servidor Ssh?

  4. 4 formas de ejecutar un script de shell en UNIX/Linux

  5. Formato de fecha y hora para script o variable de shell de Linux

Cómo ejecutar el comando / secuencia de comandos de Linux Shell en segundo plano

Los 6 mejores shells de código abierto para Linux

Cómo almacenar un comando de Linux como una variable en el script de Shell

Cómo ejecutar Shell Script como servicio SystemD en Linux

Imprimir el tiempo de ejecución de la secuencia de comandos de Shell en Linux

¿Qué es Shebang en Linux Shell Scripting?