awkを使用して配列を確認してください。

awkを使用して配列を確認してください。

私の問題は、シェルスクリプトを介して特定の文字列が互いに順列であるかどうかを確認することです。

1.Nf3 c5 2.e4 Nc6
1.e4 c5 2.Nf3 Nc6

ご覧のとおり、配列は原子の部分文字列に基づいています。つまり、両方の文字列に順序に関係なく同じ部分文字列が含まれているかどうかを知りたいのです。

AWKは高度なテキスト処理用に設計されたプログラミング言語です。だから私の考えは、2つの文字列を配列に分割することです。

{1., Nf3, c5, 2., e4, Nc6}
{1., e4, c5, 2., Nf3, Nc6}

そして、両方が同じ要素を含むかどうかを比較します。しかし、これがawk方式に適しているかどうかはわかりません。

2番目の方法は、最初の文字列をパターンに分割し{1., Nf3, c5, 2., e4, Nc6}、2番目の文字列のすべてのパターンを検索し、対応する一致に基づいて新しい文字列を作成することです。最後に、新しい文字列が最初の文字列と同じであることを確認できます。この特定のテキスト処理のためにawkに他の方法はありますか?

答え1

awk私はこれが正しいアプローチだとは思わない。文字列を分割して文字列要素を並べ替え、結果を比較します。

bash:

$ split_and_sort() { sed -r 's/\</\n/g' | sort; }

$ split_sort_and_compare() {
    if [ "$(split_and_sort <<< "$1")" = "$(split_and_sort <<< "$2")" ]
    then echo "Match"
    else echo "No match"
    fi
}

$ split_sort_and_compare "1.Nf3 c5 2.e4 Nc6" "1.e4 c5 2.Nf3 Nc6"
Match

$ split_sort_and_compare "1.Nf3 c5 2.e4 Nc6" "1.e4 c5 2.Nf3 Nc5"
No match

これは私が考えているものと文字列を分割して比較する方法の私の解釈を説明するためのおおよその例です。ルールに基づいてより複雑な機能を自分で作成してください。

答え2

参考までに、このソリューションを既存のawkプロジェクトに統合する必要がある場合に備えて、awkソリューション(非常に面倒ではありません)があります。

a="1.Nf3 c5 2.e4 Nc6"
b="1.e4 c5 2.Nf3 Nc6"
awk 'BEGIN{FS=""}{last=NF;for (i=1;i<=NF;i++) {if (NR==FNR) {a[i]=$i} else {b[i]=$i}}} \
{asort(a);asort(b)}END{{for (k=1;k<=last;k++) if (a[k]!=b[k]) nomatch++}{print (nomatch==0)?"match":"no match"}}' <(echo "$a") <(echo "$b")

2つの文字列を比較したい場合は、bashメソッドを使用するか、xhienneが提案した答えを使用するか、次のように使用します。

[[ $(sort <(grep -o . <<<"$a") |base64) == $(sort <(grep -o . <<<"$b") |base64) ]] && echo "match" || echo "differ"

どちらの場合も、ロジックは同じです。入力文字列を文字ごとに分割し、1つずつ並べ替え、並べ替えられた2つの文字列を比較します。

上記のbashメソッドでソートされた文字列をbase64でエンコードし、そのbase64値を比較したいと思います。

答え3

2つの文字列に同じ文字が含まれていることを確認するもう1つの方法は、ASCII値を合計することです。

$ while read -rn1 char;do sumA+=$(printf '%d+' "'$char'");done <<<"1.Nf3 c5 2.e4 Nc6"
$ while read -rn1 char;do sumB+=$(printf '%d+' "'$char'");done <<<"1.e4 c5 2.Nf3 Nc6"

$ echo "$sumA"
49+46+78+102+51+39+99+53+39+50+46+101+52+39+78+99+54+39+
$ echo "$sumB"
49+46+101+52+39+99+53+39+50+46+78+102+51+39+78+99+54+39+

$ bc <<<"${sumB:0:-1}"
1114
$ bc <<<"${sumA:0:-1}"
1114

同じ数字、=同じ文字列。したがって、これら2つのbc値を比較すると、一致/不一致条件が得られます。

文字列間で1文字が異なる場合、ASCII値の合計は異なります。

$ while read -rn1 char;do sumC+=$(printf '%d+' "'$char'");done <<<"1.Nf3 q5 2.e4 Nc6" #q5 is different than string A
$ echo "$sumC"
49+46+78+102+51+39+113+53+39+50+46+101+52+39+78+99+54+39+
$ bc <<<"${sumC:0:-1}"
1128

関連情報