Perlは正規表現が好きです。

Perlは正規表現が好きです。

これは簡単なはずですが、理解できません。 sedを使用してAまたはBをCに置き換えるには、コードは次のようになります。

$ echo AAXXAAYYBB | sed 's/[AB]/C/g'
CCXXCCYYCC

これにより、AとBの両方がCに変換されます。

私が望むのは、「A」を2つ(またはそれ以上)の変数の1つに置き換えることです。

入力する:

AAXXAAYYBB

パスワード:

sed 's/A/[BC]/g'

出力(BまたはCの交換がランダムである場合):

BCXXCBYYBB 

ただし、このコードはAを次にのみ変更します。

$ echo AAXXAAYYBB | sed 's/A/[BC]/g'
[BC][BC]XX[BC][BC]YYBB

可能であれば、ここではPERLを使用しないようにしています。この問題を解決する方法を知っている人はいますか?

ベストアンサー1

交換可能最初次のような文字列:

${str/A/...}

また、以下を使用して任意の(暗号的に安全な数値ではなく)値を生成できます。

r=(B C)
${r[RANDOM%2]}      

変数がr展開されるたびに。

同じですが、より速い操作は、ANDを使用して値の最後のビットを抽出することです。${r[RANDOM&1]}

だから:

#!/bin/bash

str=AAXXAAYYBB
r=(B C)

while [ "${str%"${str#*A}"}" ]; do      # while there is an A to change
    str=${str/A/"${r[RANDOM&1]}"}
done

echo "str=$str"

呼び出されるたびにランダムな結果が生成されます。

ボスケスリー

#!/bin/sh

str=AAXXAAYYZZAAA

while [ "${str%"${str#*A}"}" ]; do             # while there is an A.
    r=$(od -An -tu1 -N 1 /dev/urandom)         # get one random byte
    r=$((r&1))                                 # Is it even or odd?
    if [ "$r" -eq 0 ]; then s=B; else s=C;fi   # Select B or C 
    str="${str%%A*}${s}${str#*A}"              # Change the string.
done

echo "str=$str"

おそらく、ほとんどの場合、より速く組み込まれたprintfを使用して、より簡単ですが、より不思議な方法で任意のバイトを読み取ることができます。

r=$(printf '%d\n' "'$(head -c1 /dev/urandom)")

おすすめ記事