Проверить перестановку с помощью awk

Как упоминалось на
https://sourceware.org/ml/cygwin-announce/2015-10/msg00111.html

'- nolisten tcp 'теперь используется по умолчанию, поэтому сервер принимает только локальные соединения через сокет домена unix. Добавлена ​​опция «-listen», которую можно использовать для восстановления предыдущего поведения.

2
20.03.2017, 01:38
3 ответа

Я не думаю, что 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

Это всего лишь грубый пример, иллюстрирующий мою идею, с моей собственной интерпретацией того, как нужно разделять и сравнивать строки. Создавайте собственные более сложные функции в соответствии со своими правилами.

3
27.01.2020, 21:56

Для справки: это решение на 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 значения.

1
27.01.2020, 21:56

Альтернативный способ проверить, содержат ли обе строки одинаковые символы, - это вычислить сумму их значений 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
1
27.01.2020, 21:56

Теги

Похожие вопросы