GNU/Linux >> Linux の 問題 >  >> Linux

Linux シェルの音訳スクリプト

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

使い方:

awk -f script.awk file

テスト:

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

table[] に入力するためのより簡潔で慣用的な方法を示すためだけに、答えではありません 関連するコメントで説明されている @konsolebox の回答からの配列:

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

したがって、古い文字から新しい文字へのマッピングは、最初の split() の文字がその下の文字にマッピングされ、他のマッピングが必要な場合は、 split()、table[] への 26 っぽい明示的な代入を変更しないでください。

マッピングを行う一般的なスクリプトを作成して、古い文字列と新しい文字列を変数として渡すこともできます:

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

シェルでは次のようになります:

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

また、文字列を設定する際の間違いから身を守ることができます。例:

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

b が x に写像すると書いた後で、誤って b が y に写像すると書いた場合、それを知っておくとよいでしょうか?上記は実際にこれを行うための最良の方法ですが、もちろんあなたの呼び出しです。

以下のコメントで説明されている 1 つの完全なソリューションを次に示します。

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
}

table の名前を変更しました map の配列 配列の目的をより適切に表す iMHO という理由だけで。

上記をファイル script.awk に保存します awk -f script.awk inputfile として実行します


これは、Perl ワンライナーを使用して非常に簡潔に行うことができます:

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

または同等のもの (jaypal に感謝):

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

%h 文字 (キー) とその置換 (値) を含むハッシュです。 s は置換コマンドです (sed と同様)。 g 修飾子は置換がグローバルであることを意味し、e 置換部分が式として評価されることを意味します。各文字を 1 つずつキャプチャし、存在する場合はハッシュの値で置き換え、存在しない場合は元の値を保持します。 -p switch は、入力の各行が自動的に出力されることを意味します。

テスト:

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

Linux
  1. 初心者のためのシェルスクリプト実行ガイドライン

  2. UNIX/Linuxでシェルスクリプトを実行する4つの方法

  3. 2 Linux 用メモリ回帰 Perl スクリプト

  1. Linux シェル スクリプトで Yes/No/Cancel の入力を求めるにはどうすればよいですか?

  2. Linuxシェルスクリプトで正規表現を使用してファイルを検索する方法

  3. データベース バックアップ用の Linux シェル スクリプト

  1. Linuxシェルスクリプトで数値と文字列を比較する方法

  2. Ssh – Sshサーバーにログインするためのシェルスクリプト?

  3. 最も古いファイルを移動するためのシェルスクリプト?