LINUX.ORG.RU

Bash

 ,


0

3

Привет все форумчанам. Помогите новичку. Есть файл с номерами телефонов вида

  • 37491201927
  • 37491357821
  • 37491419271
  • 37491471041
  • 37491733963
  • 37491908682
  • 37491532464
  • 37491660914
  • 23799933583
  • 23798012784
  • 237959034650
  • 237959034650
  • 237979353011
  • 23799565811

И так далее. Есть база с кодами стран и операторов вида

  • CAMEROON ORANGE 2379
  • ARMENIA ARMENTEL 37491

нужно сделать следующее: вставить строку с названием страны и оператора перед номером. Как то так:

  • CAMEROON ORANGE 2379
  • 23799933583
  • 23798012784
  • 237959034650
  • 237959034650
  • 237979353011
  • 23799565811
  • ARMENIA ARMENTEL 37491
  • 37491201927
  • 37491357821
  • 37491419271
  • 37491471041
  • 37491733963
  • 37491908682
  • 37491532464
  • 37491660914

Я готов прописывать условия для каждого оператора и страны, только покажите как это делать на примере этих двух. Спасибо большое.



Последнее исправление: SkySon (всего исправлений: 3)

Я ничего не понял. Что это за «база», как она выглядит? И в чем у вас, собственно, возникла проблема?

Zmicier ★★★★★
()
Ответ на: *slowpoke от SkySon

Товарищ прозрачно намекает (как вам, так и и модератору), что, судя по постановке вопроса, вы ошиблись подфорумом.

Наверное нужно пояснить, что несмотря на то, что в описании подфорума «Job» сказано, что он только для вакансий и резюме, ветки типа «напишите мне скрипт за вознаграждение» публикуются, обычно, там же.

Zmicier ★★★★★
()
Последнее исправление: Zmicier (всего исправлений: 2)

Ага, теперь вижу, что за база.

Но на будущее, не ограничивайтесь правкой письма, когда хотите что-то сообщить — здесь уведомления приходят только о новых сообщениях, не об исправлениях.

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

Я понял, спасибо за пояснение. Это сложная задача? Просто думал что решение элементарное и мне кто нибудь подскажет бесплатно) да-да, я такой же как и все, любитель халявы

SkySon
() автор топика
Ответ на: комментарий от ugoday

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

SkySon
() автор топика
Ответ на: комментарий от SkySon

Вот «элементарное» (костыльное) решение:

$ cat codes 
CAMEROON ORANGE 2379
ARMENIA ARMENTEL 37491 

$ cat numbers 
37491201927
37491357821
37491419271
37491471041
37491733963
37491908682
37491532464
37491660914
23799933583
23798012784
237959034650
237959034650
237979353011
23799565811 

$ while read line ; do echo $line; grep "^$(echo $line | awk '{print $NF}')" numbers; echo; done < codes
CAMEROON ORANGE 2379
23799933583
23798012784
237959034650
237959034650
237979353011
23799565811 

ARMENIA ARMENTEL 37491
37491201927
37491357821
37491419271
37491471041
37491733963
37491908682
37491532464
37491660914

alozovskoy ★★★★★
()
Последнее исправление: alozovskoy (всего исправлений: 1)
Ответ на: комментарий от alozovskoy

Спасибо огромное) Мир не без добрых людей)

SkySon
() автор топика

На баше такое заманаешься делать. Коды-то перекрываются, 8 - код абстрактной России, если большие ничего про номер неизвестно. А 8921 - Мегафон.

Таких кодов и по России хватает, про всемирность и говорить нечего.

Так что ставишь библиотеку для префиксного поиска, marisa-trie

pip3 install marisa-trie

И фигачишь программу на питоне:

#!/usr/bin/python3

import marisa_trie

prefix_data = {
    '2379': 'Cameroon 2379', 
    '37491': 'Armenia 37491'
    # А дальше куча-куча других кодов, городов и стран
}

trie = marisa_trie.Trie(prefix_data.keys())

# Находим максимально конкретный, т.е. самый длинный, префикс.
# И по нему достаем описание.
def get_descr(phone):
    phone_prefixes = trie.prefixes(phone)
    pref = max(phone_prefixes, key=len)
    if pref == None: return "Unknown " + phone
    return prefix_data[pref]

# Если у новой строки префикс отличается от предыдущей, то пишем
# в файл лишнюю строку с описанием
cur_descr = None
prev_descr = None

output = open('/tmp/phones_output.txt', 'w')

for line in open('/tmp/phones.txt', 'r'):
    cur_descr = get_descr(line)
    if cur_descr != prev_descr:
        output.write(cur_descr)
        output.write('\n')
        prev_descr = cur_descr
    output.write(line)

output.flush()

Входной файл - /tmp/phones.txt

37491201927
37491357821
37491419271
37491471041
37491733963
37491908682
37491532464
37491660914
23799933583
23798012784
237959034650
237959034650
237979353011
23799565811

Выходной, /tmp/phones-output.txt

Armenia 37491
37491201927
37491357821
37491419271
37491471041
37491733963
37491908682
37491532464
37491660914
Cameroon 2379
23799933583
23798012784
237959034650
237959034650
237979353011
23799565811

В идеале, конечно, входной файл нужно бы отсортировать, но это по обстоятельствам.

cat /tmp/phones.txt  | sort > /tmp/phones.sorted.txt
anonymous
()
Ответ на: комментарий от anonymous

Ого, выглядит очень красиво и удобно. Python очень элегантный язык) Спасибо вам за помощь.

SkySon
() автор топика
Ответ на: комментарий от Suntechnic

Стран, конечно, всего две сотни. Но даже внутри России операторов/регионов именно тысячи.

http://www.rossvyaz.ru/activity/num_resurs/registerNum/

Можешь полюбоваться на «Коды DEF-9х», лучше в csv-формате, html-таблица такого размера тормозит и жгёт процессор.

anonymous
()
Ответ на: комментарий от anonymous

А можно сделать так, чтобы список был не в скрипте, а в отдельно лежащем файле? prefix_data = { '2379': 'Cameroon 2379', '37491': 'Armenia 37491' # А дальше куча-куча других кодов, городов и стран }

SkySon
() автор топика
Ответ на: комментарий от SkySon

Любой каприз за ваши деньги:

prefix_data = {l.split()[-1] : l.strip() for l in open('/tmp/codes.txt')}

l.split() - разбивает строку по пробелам, [-1] - берет из них последний элемент, т.е. код. l.strip() - убивает лишние '\n'.

/tmp/codes.txt:

CAMEROON        ORANGE  2379
ARMENIA ARMENTEL        37491

anonymous
()
Ответ на: комментарий от anonymous

Так что ставишь библиотеку для префиксного поиска, marisa-trie

Достаточно отсортировать по префиксам в порядке убывания.

anonymous
()
Ответ на: комментарий от anonymous

Да, достаточно. Но поиск будет брутфорсом, с самого первого элемента, и пока не встретится нужная приставка, или не встретится ничего.

Наверняка придется оптимизировать, например, если номер с тройки начинается, то префиксы с другой цифры можно и не рассматривать. Но у той же России фигова туча номеров, и все с одной и той же восьмерки. Так что захочется проверять сразу пару цифр, и пошло-поехало, в конечном итоге к тому же trie и придем.

Проще сразу взять готовую либу, кода всего пару строк добавляет.

anonymous
()

А кто мешает эти коды передвинуть на первую позицию?

Вместо

CAMEROON	ORANGE	2379
ARMENIA	ARMENTEL	37491
сделать
2379 CAMEROON	ORANGE
37491 ARMENIA	ARMENTEL
потом сложить два файла и запустить всего одну команду sort res.txt, которая сделает всё, что нужно.

justAmoment ★★★★★
()
Ответ на: комментарий от ToaDron

И всё таки LOR иногда прекрасен =3

просто многим бывает реально нечего делать(

quest ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.