내 문제는 쉘 스크립트를 통해 특정 문자열이 서로 순열인지 여부를 확인하는 것입니다.
1.Nf3 c5 2.e4 Nc6
1.e4 c5 2.Nf3 Nc6
보시다시피 배열은 원자의 하위 문자열을 기반으로 합니다. 즉, 두 문자열에 순서에 관계없이 동일한 하위 문자열이 포함되어 있는지 알고 싶습니다.
AWK는 고급 텍스트 처리를 위해 설계된 프로그래밍 언어입니다. 그래서 나온 아이디어는 두 문자열을 배열로 분할하는 것입니다.
{1., Nf3, c5, 2., e4, Nc6}
{1., e4, c5, 2., Nf3, Nc6}
그리고 둘 다 동일한 요소를 포함하는지 비교하십시오. 하지만 이것이 awk 방식에 적합한지는 잘 모르겠습니다.
두 번째 방법은 첫 번째 문자열을 패턴으로 분할 {1., Nf3, c5, 2., e4, Nc6}
하고 두 번째 문자열의 모든 패턴을 검색하고 해당 일치 항목을 기반으로 새 문자열을 만드는 것입니다. 결국 새 문자열이 첫 번째 문자열과 같은지 확인할 수 있습니다. 이 특정 텍스트 처리를 위해 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")
두 문자열을 비교하고 싶다면 bash 방식을 사용하거나 xhienne이 제안한 답변을 사용하거나 다음과 같이 사용합니다.
[[ $(sort <(grep -o . <<<"$a") |base64) == $(sort <(grep -o . <<<"$b") |base64) ]] && echo "match" || echo "differ"
두 경우 모두 논리는 동일합니다. 입력 문자열을 문자별로 분할한 후 하나씩 정렬하고, 정렬된 두 문자열을 비교합니다.
위의 bash 방식에서 정렬된 문자열을 base64로 인코딩하고 해당 base64 값을 비교하고 싶습니다.
답변3
두 문자열에 동일한 문자가 포함되어 있는지 확인하는 또 다른 방법은 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
같은 숫자, = 같은 문자열. 따라서 이 두 bc 값을 비교하면 일치/불일치 조건을 얻을 수 있습니다.
문자열 사이에 한 문자가 다르면 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