Люблю погонять AWK

Mar 02, 2010 14:05

Простая практическая задача, выудить из HTML имена и фамилии учеников из списка окончивших школу и списка поступивших в вуз, сравнить и выдать совпавшие. AWK хорошо подходит для подобных задач, кроме того, я уже имел опыт работы с ним, поэтому на нём и остановился. Задача несколько осложнена тем, что исходные файлы в разной кодировке - UTF-8 и ISO-8859-1, причём встречаются HTML-мнемоники и неверное указание кодировки (некоторые эстонские символы с диакритикой в CP1252, неверно указан ISO-8859-1). В таком случае можно всё перекодировать в UTF-8, а уже затем сравнивать.
  1. Вытаскиваем имена и фамилии из HTML-файла в кодировке UTF-8:
    ## Extract and change order to
    # e.g. from
    # 1
    # Allik, Erik
    #
    BEGIN {
    RS = "|"
    FS = "," }
    /^[[:alpha:]]+/ { print $2, $1 }
    Вытаскиваем имена и фамилии из HTML-файла в кодировке ISO-8859-1, по пути перекодируя в эстонские символы в UTF-8:
    ## Extract
    # e.g. from
    # 85. Simmo Sirel
    #
    BEGIN {
    RS = "|"
    FS = "." }
    /^\x20*[0-9]+/ { print html2utf8(cp12522utf8($2)) }

    ## Recode HTML entities to UTF-8 symbols
    #
    function html2utf8(s) {
    gsub("Ä", "\xC3\x84", s)
    gsub("ä", "\xC3\xA4", s)
    gsub("Ö", "\xC3\x96", s)
    gsub("ö", "\xC3\xB6", s)
    gsub("Ü", "\xC3\x9C", s)
    gsub("ü", "\xC3\xBC", s)
    gsub("Õ", "\xC3\x95", s)
    gsub("õ", "\xC3\xB5", s)
    gsub("Š", "\xC5\xA0", s)
    gsub("š", "\xC5\xA1", s)
    gsub("Ž", "\xC5\xBD", s)
    gsub("ž", "\xC5\xBE", s)
    return s }

    ## Recode CP1252 to UTF-8 symbols
    #
    function cp12522utf8(s) {
    gsub("\xC4", "\xC3\x84", s) # Ä
    gsub("\xE4", "\xC3\xA4", s) # ä
    gsub("\xD6", "\xC3\x96", s) # Ö
    gsub("\xF6", "\xC3\xB6", s) # ö
    gsub("\xDC", "\xC3\x9C", s) # Ü
    gsub("\xFC", "\xC3\xBC", s) # ü
    gsub("\xD5", "\xC3\x95", s) # Õ
    gsub("\xF5", "\xC3\xB5", s) # õ
    gsub("\x8A", "\xC5\xA0", s) # Š
    gsub("\x9A", "\xC5\xA1", s) # š
    gsub("\x8E", "\xC5\xBD", s) # Ž
    gsub("\x9E", "\xC5\xBE", s) # ž
    return s }
  2. Чистим, удаляя ненужные пробелы и пустые строки:
    ## Remove some spaces and fix strange events
    #
    { gsub(/^\x20+|\x20+$/, "") # remove leading and trailing spaces
    gsub("\x20+", "\x20") # remove multiple spaces
    gsub("\\.", "-") # Kaia.Liisa event from school.txt
    if (NF > 0) print } # remove blank lines
  3. Простое сравнение:
    ## Print equal lines from two files
    #
    { while ((getline line < f) > 0) if (line == $0) { print; break } close(f) }
    Мягкое сравнение, c учётом того, что эстонские символы с диактитикой могли быть неправильно переданы или заменены на аналогичные без диакритик:
    ## Print equal (compared w/ simplifying) lines from two files
    #
    { while ((getline line < f) > 0) if (simplifyutf8(line) == simplifyutf8($0)) {
    if (tolower(line) == tolower($0)) print
    else print $0 " (" line ")"
    break }
    close(f) }

    ## Simplify estonian UTF-8 symbols w/ diacritic
    #
    function simplifyutf8(s) {
    gsub ("\xC3\x84", "A", s)
    gsub ("\xC3\xA4", "a", s)
    gsub ("\xC3\x96", "O", s)
    gsub ("\xC3\xB6", "o", s)
    gsub ("\xC3\x9C", "U", s)
    gsub ("\xC3\xBC", "u", s)
    gsub ("\xC3\x95", "O", s)
    gsub ("\xC3\xB5", "o", s)
    gsub ("\xC5\xA0", "S", s)
    gsub ("\xC5\xA1", "s", s)
    gsub ("\xC5\xBD", "Z", s)
    gsub ("\xC5\xBE", "z", s)
    return tolower(s) }
Все файлы, включая wget.exe и gawk.exe: school-db_w_wget_and_gawk.zip

Использованное ПО: Wget 1.11.4, Gawk 3.1.7
Подсветка кода: Online syntax highlighting

скрипт, диакритика, howto, awk, iso 8859-1, utf-8, cp1252

Previous post Next post
Up