AWK:辞書のソース用語の後にランダムに選択されたターゲット用語行を挿入します。

AWK:辞書のソース用語の後にランダムに選択されたターゲット用語行を挿入します。

注:すでに同様の質問がありました。AWK:ソース用語の後にターゲット単語を挿入する簡単な方法そして私はAWKの初級レベルです。

この問題は、ランダムに選択された複数行のソース用語の後に複数のターゲット用語を挿入することを考慮しています。

このAWKコードスニペットを使用すると、

awk '(NR==FNR){a[$1];next}
    FNR in a { gsub(/\<source term\>/,"& target term") }
     1
    ' <(shuf -n 5 -i 1-$(wc -l < file)) file

5つのランダム行target termの後に1つを挿入したいと思います。source termfile

例:dict左側にソース用語が含まれ、右側にターゲット用語が含まれるバイリンガル辞書があります。

apple     : Apfel
banana    : Banane
raspberry : Himbeere

鉱山はfile次の行で構成されています。

I love the Raspberry Pi.
The monkey loves eating a banana.
Who wants an apple pi?
Apple pen... pineapple pen... pen-pineapple-apple-pen!
The banana is tasty and healthy.
An apple a day keeps the doctor away.
Which fruit is tastes better: raspberry or strawberry?

最初の単語appleに対してランダムな行1、3、5、4、7が選択されているとします。 appleという単語を含む出力は次のとおりです。

I love the Raspberry Pi.
The monkey loves eating a banana.
Who wants an apple Apfel pi?
Apple Apfel pen... pineapple pen... pen-pineapple-apple-pen!
The banana is tasty and healthy.
An apple a day keeps the doctor away.
Which fruit is tastes better: raspberry or strawberry?

bananaその後、選択する単語に5つのランダムな行が追加されます。

I love the Raspberry Pi .
The monkey loves eating a banana .
Who wants an apple Apfel pi ?
Apple Apfel pen... pineapple pen... pen-pineapple-apple-pen!
The banana Banane is tasty and healthy .
An apple a day keeps the doctor away .
Which fruit is tastes better: raspberry or strawberry?

dict他のすべての項目は、最後の項目が一致するまで続きます。

ランダムに5本のラインを選びたいです。行に完全なソース用語が含まれている場合は、単語全体をapple一致させようとします(「pineapple」などの用語は無視されます)。たとえば、1行にソース用語が2回含まれている場合は、その後にターゲット用語を挿入したいと思います。一致は大文字と小文字を区別する必要があるため、同じソース用語も一致させることができます。ApfelappleappleappleApple

dict私の質問:辞書が利用可能で辞書を選択できるように、上記のコードスニペットをどのように書き換えますか?ランダム行をクリックfileし、ソース用語の後にターゲット用語を挿入しますか?

ベストアンサー1

以下は、awkを使用して入力ファイル内の5つの行番号をランダムに選択する方法です(最初のパスでwcを使用すると行番号のみが計算されます)。

$ awk -v numLines="$(wc -l < file)" 'BEGIN{srand(); for (i=1; i<=5; i++) print int(1+rand()*numLines)}'
7
2
88
13
18

もう持って行けばいい私の以前の答えブロックから読み取られた各「前の」文字列について、ARGIND==1上記のように5つの行番号を生成し、配列を埋め、生成された行番号を各行番号に関連付けられている前の文字列にマップし、ファイルを読み込みます。最後に、ファイルが入力されたら確認します。行番号が現在の配列にあり、そうである場合は、その行番号の配列に格納されている「前」を繰り返し、前の回答gsub()で示した操作を実行します。

ARGIND、、IGNORECASE単語の境界、配列の配列、および:の省略形\sを表すには、GNU awkを使用します。[[:space:]]

$ cat tst.sh
#!/usr/bin/env bash

awk -v numLines=$(wc -l < file) '
    BEGIN {
        FS = "\\s*:\\s*"
        IGNORECASE = 1
        srand()
    }
    ARGIND == 1 {
        old = "\\<" $1 "\\>"
        new = "& " $2
        for (i=1; i<=5; i++) {
            lineNr = int(1+rand()*numLines)
            map[lineNr][old] = new
        }
        next
    }
    FNR in map {
        for ( old in map[FNR] ) {
            new = map[FNR][old]
            gsub(old,new)
        }
    }
    { print }
' dict file

$ ./tst.sh
I love the Raspberry Pi.
The monkey loves eating a banana Banane.
Who wants an apple Apfel pi?
Apple Apfel pen... pineapple pen... pen-pineapple-apple Apfel-pen!
The banana Banane is tasty and healthy.
An apple a day keeps the doctor away.
Which fruit is tastes better: raspberry Himbeere or strawberry?

おすすめ記事