Проблема форматирования блоков строк

1

Я работаю над тем, чтобы автоматически загружать параметры землетрясений из Национального информационного центра землетрясений (USGS). К сожалению, их формат - это куча дерьма, и я не думаю, что мне удастся убедить их изменить их формат. Итак, я должен отформатировать их <pre> блок html, чтобы поместить его в табличную форму.

Но мой опыт с форматированием строк ограничен, поэтому я застрял (но уверен, что там кто-то, у кого может быть решение). Вот пример:

curl --silent http://earthquake.usgs.gov/earthquakes/eqinthenews/2010/uu00002715/uu00002715_gcmt.php |\
sed -n '/<pre>/,/<\/pre>/p' |\
egrep -v '(#)|(pre>)' |\
egrep '(MW)|(ORIGIN)|(LAT)|(DEP)|(BEST DBLE)|(NP1)'

который дает необходимую мне информацию:

April 15, 2010, UTAH, MW=4.6
ORIGIN TIME:      23:59:42.8 0.4
LAT:41.72N 0.03;LON:110.86W 0.03
DEP: 12.5  1.8;TRIANG HDUR:  0.6
BEST DBLE.COUPLE:M0= 1.07*10**23
NP1: STRIKE=193;DIP=35;SLIP= -80

Я хотел бы получить такой формат:

name date       time       lon     lat   dep  dep_err Mw  M0      strike dip slip
UTAH 2010/04/15 23:59:42.8 -110.86 41.72 12.5 1.8     4.6 1.07e23 193    35  -80

Обратите внимание, что долгота должна быть преобразована в восточную долготу (следовательно, смена знака).

Я хотел бы, чтобы решение unix shell командах unix shell awk, python или unix shell, но я бы включил ruby или perl (я просто, вероятно, не пойму, что происходит).

Теги:
string
awk
formatting

3 ответа

1
Лучший ответ

Вот скрипт awk, который доставит вам большую часть пути. Преобразование Lon, date, M0 и т.д. Остается в качестве упражнения:

curl --silent http://earthquake.usgs.gov/earthquakes/eqinthenews/2010/uu00002715/uu00002715_gcmt.php |
awk '
    BEGIN {
        FS = "[,:;= ]+"
        OFS = "^"
    }
    /<pre>/ {process=1}
    /<\/pre>/ {process=0}
    ! process {next}
    /MW=/ {
        date = $1 " " $2 " " $3
        place = $4
        mw = $NF
    }
    /^ORIGIN TIME:/ {
        otime = $3 ":" $4 ":" $5
    }
    /^LAT:.*LON:/ {
        lat = $2
        lon = $5
    }
    /^DEP:/ {
        dep = $2
        dep_err = $3
    }
    /^BEST DBLE.COUPLE:/ {
        m0 = $NF
    }
    /^NP1:/ {
        strike = $3
        dip = $5
        slip = $7
    }
    END {
        print "name", "date", "time", "lon", "lat", "dep", "dep_err", "Mw", "M0", "strike", "dip", "slip"
        print place, date, otime, lon, lat, dep, dep_err, mw, m0, strike, dip, slip
    }
' | column -s ^ -t

Вывод:

name  date           time        lon      lat     dep   dep_err  Mw   M0           strike  dip  slip
UTAH  April 15 2010  23:59:42.8  110.86W  41.72N  12.5  1.8      4.6  1.07*10**23  193     35   -80
  • 0
    Я унижен. Спасибо вам большое!
3

Почему бы просто не использовать один из своих XML-форматированных каналов, таких как этот. Я уверен, что легче разобрать.

  • 0
    Я ценю это предложение. Вопрос научный: мне нужно убедиться, что решение, которое они публикуют (и я использую), является окончательной оценкой, а не первоначальной оценкой. Во многих случаях их опубликованная модель дорабатывается от нескольких часов до нескольких дней, поэтому я не могу рассчитывать на немедленную подачу RSS.
2

Разбор html с регулярными выражениями обычно рассматривается как очень и очень плохая идея, поэтому я бы предложил Abizern использовать RSS-канал. Фактически, USGS также предоставляет загрузки XML (см. Http://earthquake.usgs.gov/earthquakes/catalogs/).

Если по какой-то причине вы не можете этого сделать и должны использовать html, то, поскольку блок <pre> не имеет никакой дополнительной структуры (исключая что-то приятное, например, используя lxml или beautifulsoup), для этого одного примера работает следующий python.. Регулярное выражение, вероятно, очень хрупкое (и, откровенно говоря, cludgey) и нуждается в настройке для обработки других примеров/исключений.

Это записывается в файл excel, поэтому вы можете вытащить все это в цикле, чтобы очистить несколько страниц (играть хорошо и проверять их условия, ограничивать скорость и кеш).

import httplib2
import re
from xlwt import Workbook

h = httplib2.Http(".cache")
url = 'http://earthquake.usgs.gov/earthquakes/eqinthenews/2010/uu00002715/uu00002715_gcmt.php'
resp, content = h.request(url, "GET")
regex = re.compile("<pre>\s*(?P<date>.* \d{2}, \d{4}), (?P<name>\w.*), MW=(?P<Mw>\d.\d).*ORIGIN TIME:\s*(?P<time>\d{2}:\d{2}:\d{2}.\d).*LAT:\s*(?P<lat>\d{2,3}.\d{2,3}[N|S]).*LON:\s*(?P<lon>\d{2,3}.\d{2,3}[W|E]).*DEP:\s*(?P<dep>\d{2,3}.\d)\s*(?P<dep_err>\d{1,3}.\d);.*M0=\s*(?P<M0>\d.\d{1,2}\*\d{1,2}\*\*\d{1,2}).*STRIKE=(?P<strike>\d{1,3}).*DIP=(?P<dip>\d{1,3}).*SLIP=\s*(?P<slip>[-|+]\d{1,3}).*NP2",re.MULTILINE|re.DOTALL)
r = regex.search(content)
data = r.groupdict()

headers = ['name', 'date', 'time', 'lon', 'lat', 'dep', 'dep_err', 'Mw', 'M0', 'strike', 'dip', 'slip']
wb = Workbook()
ws = wb.add_sheet('Quakes')

column = 0
for header in headers:
    ws.write(0, column, header)
    ws.write(1, column,data[header])
    column+=1
wb.save('quakes.xls')

Вы должны определенно использовать XML/RSS, но если вы можете :)

  • 0
    Это очень хорошее решение @craigs. Проблема, да, я должен использовать HTML (см. Мой ответ на @Abizern).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню