GNU/Linux >> Belajar Linux >  >> Linux

Skrip transliterasi untuk shell linux

Menggunakan 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

Penggunaan:

awk -f script.awk file

Tes:

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

Bukan jawaban, hanya untuk menunjukkan cara yang lebih singkat dan idiomatis untuk mengisi table[] array dari jawaban @konsolebox seperti yang dibahas dalam komentar terkait:

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

jadi pemetaan karakter lama ke baru ditampilkan dengan jelas bahwa karakter di split() pertama dipetakan ke karakter di bawahnya dan untuk pemetaan lain yang Anda inginkan, Anda hanya perlu mengubah string di split(), bukan mengubah penetapan eksplisit 26-ish ke table[].

Anda bahkan dapat membuat skrip umum untuk melakukan pemetaan dan hanya meneruskan string lama dan baru sebagai variabel:

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

lalu di shell seperti ini:

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

dan Anda dapat melindungi diri dari kesalahan Anda sendiri dalam mengisi string, misalnya:

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

Bukankah lebih baik untuk mengetahui jika Anda menulis bahwa b memetakan ke x dan kemudian secara keliru menulis bahwa b memetakan ke y? Di atas benar-benar adalah cara terbaik untuk melakukan ini tetapi panggilan Anda tentu saja.

Inilah satu solusi lengkap seperti yang dibahas dalam komentar di bawah

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
}

Saya mengganti nama table array sebagai map hanya karena iMHO yang lebih mewakili tujuan dari array.

simpan di atas dalam file script.awk dan jalankan sebagai awk -f script.awk inputfile


Ini dapat dilakukan dengan cukup ringkas menggunakan Perl one-liner:

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

atau yang setara (terima kasih jaypal):

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

%h adalah hash yang berisi karakter (kunci) dan penggantinya (nilai). s adalah perintah substitusi (seperti pada sed). g pengubah berarti substitusi bersifat global dan e berarti bahwa bagian pengganti dievaluasi sebagai ekspresi. Itu menangkap setiap karakter satu per satu dan menggantinya dengan nilai di hash jika ada, jika tidak, simpan nilai aslinya. -p switch berarti bahwa setiap baris dalam input dicetak secara otomatis.

Mengujinya:

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

Linux
  1. 5 Ekstensi Shell GNOME Terbaik untuk Desktop Linux Anda

  2. Script Shell Untuk Memindahkan File Terlama?

  3. Format tanggal dan waktu untuk skrip atau variabel shell Linux

  1. Bagaimana saya meminta input Ya/Tidak/Batalkan dalam skrip shell Linux?

  2. konvensi penamaan untuk skrip shell dan makefile

  3. Skrip shell Linux untuk cadangan basis data

  1. Ssh – Skrip Shell Untuk Masuk Ke Server Ssh?

  2. Panduan Eksekusi Skrip Shell untuk Pemula

  3. Membuat template dengan Linux dalam Shell Script?