Пример A-10. Расчет индекса "созвучности"

Пример A-10. Расчет индекса "созвучности"

  1. #!/bin/bash
  2. # soundex.sh: Расчет индекса "созвучности"
  3. # =======================================================
  4. #       Сценарий Soundex
  5. #            Автор
  6. #         Mendel Cooper
  7. #     thegrendel@theriver.com
  8. #       23 Января 2002 г.
  9. #
  10. #   Условия распространения: Public Domain.
  11. #
  12. # Несколько отличающаяся версия этого сценария была опубликована
  13. #+ Эдом Шэфером (Ed Schaefer) в Июле 2002 года в колонке "Shell Corner"
  14. #+ "Unix Review" on-line,
  15. #+ <a href="http://www.unixreview.com/documents/uni1026336632258/
  16. #" title="http://www.unixreview.com/documents/uni1026336632258/
  17. #">http://www.unixreview.com/documents/uni1026336632258/
  18. #</a> =======================================================
  19. ARGCOUNT=1                     # Требуется аргумент командной строки.
  20. E_WRONGARGS=70
  21. if [ $# -ne "$ARGCOUNT" ]
  22. then
  23.   echo "Порядок использования: `basename $0` имя"
  24.   exit $E_WRONGARGS
  25. fi
  26. assign_value ()                #  Присвоить числовые значения
  27. {                              #+ символам в имени.
  28.   val1=bfpv                    # 'b,f,p,v' = 1
  29.   val2=cgjkqsxz                # 'c,g,j,k,q,s,x,z' = 2
  30.   val3=dt                      #  и т.п.
  31.   val4=l
  32.   val5=mn
  33.   val6=r
  34. # Попробуйте разобраться в том, что здесь происходит.
  35. value=$( echo "$1" \
  36. | tr -d wh \
  37. | tr $val1 1 | tr $val2 2 | tr $val3 3 \
  38. | tr $val4 4 | tr $val5 5 | tr $val6 6 \
  39. | tr -s 123456 \
  40. | tr -d aeiouy )
  41. # Символам в имени присваиваются числовые значения.
  42. # Удаляются повторяющиеся числа, если они не разделены гласными.
  43. # Гласные игнорируются, если они не являются разделителями, которые удаляются в последнюю очередь.
  44. # Символы 'w' и 'h' удаляются в первую очередь.
  45. }
  46. input_name="$1"
  47. echo
  48. echo "Имя = $input_name"
  49. # Перевести все символы в имени в нижний регистр.
  50. # ------------------------------------------------
  51. name=$( echo $input_name | tr A-Z a-z )
  52. # ------------------------------------------------
  53. # Начальный символ в индекса "созвучия": первая буква в имени.
  54. # --------------------------------------------
  55. char_pos=0                     # Начальная позиция в имени.
  56. prefix0=${name:$char_pos:1}
  57. prefix=`echo $prefix0 | tr a-z A-Z`
  58.                                # Первую букву в имени — в верхний регистр.
  59. let "char_pos += 1"            # Передвинуть "указатель" на один символ.
  60. name1=${name:$char_pos}
  61. # ++++++++++++++++++++++++++++ Исключение отдельных ситуаций +++++++++++++++++++++++++++++++
  62. #  Теперь мы передвинулись на один символ вправо.
  63. #  Если второй символ в имени совпадает с первым
  64. #+ то его нужно отбросить.
  65. #  Кроме того, мы должны проверить — не является ли первый символ
  66. #+ гласной, 'w' или 'h'.
  67. char1=`echo $prefix | tr A-Z a-z`    # Первый символ — в нижний регистр.
  68. assign_value $name
  69. s1=$value
  70. assign_value $name1
  71. s2=$value
  72. assign_value $char1
  73. s3=$value
  74. s3=9$s3                              #  Если первый символ в имени — гласная буква
  75.                                      #+ или 'w' или 'h',
  76.                                      #+ то ее "значение" нужно отбросить.
  77.                                      #+ Поэтому ставим 9, или другое
  78.                                      #+ неиспользуемое значение, которое можно будет проверить.
  79. if [[ "$s1" -ne "$s2" || "$s3" -eq 9 ]]
  80. then
  81.   suffix=$s2
  82. else
  83.   suffix=${s2:$char_pos}
  84. fi
  85. # ++++++++++++++++++++++++ Конец исключения отдельных ситуаций +++++++++++++++++++++++++++++++
  86. padding=000                    # Дополнить тремя нулями.
  87. soun=$prefix$suffix$padding    # Нули добавить в конец получившегося индекса.
  88. MAXLEN=4                       # Ограничить длину индекса 4-мя символами.
  89. soundex=${soun:0:$MAXLEN}
  90. echo "Индекс созвучия = $soundex"
  91. echo
  92. #  Индекс "созвучия" - это метод индексации и классификации имен
  93. #+ по подобию звучания.
  94. #  Индекс "созвучия" начинается с первого символа в имени,
  95. #+ за которым следуют 3-значный расчетный код.
  96. #  Имена, которые произносятся примерно одинаково, имеют близкие индексы "созвучия".
  97. #   Например:
  98. #   Smith и Smythe — оба имеют индекс "созвучия" "S530".
  99. #   Harrison = H625
  100. #   Hargison = H622
  101. #   Harriman = H655
  102. #  Как правило эта методика дает неплохой результат, но имеются и аномалии.
  103. #
  104. #
  105. #  Дополнительную информацию вы найдете на
  106. #+ "National Archives and Records Administration home page",
  107. #+ <a href="http://www.nara.gov/genealogy/soundex/soundex.html
  108. #" title="http://www.nara.gov/genealogy/soundex/soundex.html
  109. #">http://www.nara.gov/genealogy/soundex/soundex.html
  110. #</a> Упражнение:
  111. # ----------
  112. # Упростите блок "Исключение отдельных ситуаций" .
  113. exit 0