У меня есть два файла с примерно 12900 и 4400 записями соответственно, к которым я хочу присоединиться. Файлы содержат информацию о местонахождении всех наземных станций наблюдения за погодой по всему миру. Самый большой файл обновляется раз в две недели, а меньший раз в год или около того. Оригинальные файлы можно найти здесь ( http://www.wmo.int/pages/prog/www/ois/volume-a/vola-home.htm и http://weather.rap.ucar.edu/surface/ station.txt ). Мои файлы уже обрабатываются мной с помощью смешанного скрипта awk, sed и bash. Я использую файлы для визуализации данных, используя пакет GEMPAK, который можно бесплатно получить в Unidata. Самый большой файл будет работать с GEMPAK, но только не с его полной возможностью. Для этого необходимо объединение.
Файл 1 содержит информацию о местоположении станций наблюдения за погодой, где первые 6 цифр являются уникальным идентификатором станции. Различные параметры (номер станции, название станции, код страны, долгота широты и высота места станции) определяются только ее положением в строке, т.е. без вкладок.
060090 AKRABERG FYR DN 6138 -666 101
060100 VAGA FLOGHAVN DN 6205 -728 88
060110 TORSHAVN DN 6201 -675 55
060120 KIRKJA DN 6231 -631 55
060130 KLAKSVIK HELIPORT DN 6221 -656 75
060160 HORNS REV A DN 5550 786 21
060170 HORNS REV B DN 5558 761 10
060190 SILSTRUP DN 5691 863 0
060210 HANSTHOLM DN 5711 858 0
060220 TYRA OEST DN 5571 480 43
060240 THISTED LUFTHAVN DN 5706 870 8
060290 GROENLANDSHAVNEN DN 5703 1005 0
060300 FLYVESTATION AALBORG DN 5708 985 13
060310 TYLSTRUP DN 5718 995 0
060320 STENHOEJ DN 5736 1033 56
060330 HIRTSHALS DN 5758 995 0
060340 SINDAL FLYVEPLADS DN 5750 1021 28
Файл 2 содержит уникальный идентификатор в файле 1 и второй четырехзначный идентификатор (локатор ИКАО).
060100 EKVG
060220 EKGF
060240 EKTS
060300 EKYT
060340 EKSN
060480 EKHS
060540 EKHO
060600 EKKA
060620 EKSV
060660 EKVJ
060700 EKAH
060780 EKAT
Я хочу объединить два файла, чтобы получающийся файл имел 4-символьный идентификатор в первых 4 позициях строки, то есть идентификатор должен заменить 4 пробела.
060090 AKRABERG FYR DN 6138 -666 101
EKVG 060100 VAGA FLOGHAVN DN 6205 -728 88
060110 TORSHAVN DN 6201 -675 55
060120 KIRKJA DN 6231 -631 55
060130 KLAKSVIK HELIPORT DN 6221 -656 75
060160 HORNS REV A DN 5550 786 21
060170 HORNS REV B DN 5558 761 10
060190 SILSTRUP DN 5691 863 0
060210 HANSTHOLM DN 5711 858 0
EKGF 060220 TYRA OEST DN 5571 480 43
EKTS 060240 THISTED LUFTHAVN DN 5706 870 8
060290 GROENLANDSHAVNEN DN 5703 1005 0
EKYT 060300 FLYVESTATION AALBORG DN 5708 985 13
060310 TYLSTRUP DN 5718 995 0
060320 STENHOEJ DN 5736 1033 56
060330 HIRTSHALS DN 5758 995 0
EKSN 060340 SINDAL FLYVEPLADS DN 5750 1021 28
Возможно ли выполнить эту задачу с помощью некоторого сценария bash и / или awk?
источник
Ответы:
источник
Пара из нас хотела посмотреть, сможем ли мы решить эту проблему, используя
join
только. Это моя попытка сделать это. Так как это частично работает, @Terdon должен мне обед 8-).Команда
пример
подробности
Вышесказанное использует практически все доступные опции,
join
которые говорят моему инстинкту, что мы используем его неправильно, как в каком-то смысле Франкенштейна, но мы все здесь учимся, так что все в порядке ... я думаю.Переключатель
-a1
сообщает соединению включить все строки, которые не имеют соответствующего совпадения с файлом file2 в файле file1. Вот что заставляет эти строки отображаться:-1 1
И-2 1
говорят , какие столбцы , чтобы присоединиться к линии из 2 -х файлов, в основном , их 1 - й колонны.-o ...
Говорит , какие столбцы из 2 -х файлов для отображения и в каком порядке.-e "N/A"
Говорит , чтобы использовать строку «N / A» в качестве значения держателя места для печати для полей, которые считаются пустыми поjoin
.Последние 2 аргумента подают 2 файла
file1
иfile2
сортируются в команде соединения.Пожалуйста, будьте добры, так как эта работа еще не завершена
join
, и мы пытаемся продемонстрировать, как можно решить проблему такого типа с помощью команды, поскольку это, похоже, тип проблемы, для которой она предназначена.Нерешенные вопросы
3-я колонна
Главный из них - как бороться с 3-м столбцом, так как он представляет собой смесь значений из 1 слова и 2 слов. Это кажется серьезным камнем преткновения,
join
и я не могу найти способ обойти это. Любое руководство будет оценено.Разнос
Весь первоначальный интервал потерян,
join
и я не вижу способа его сохранить. Такjoin
что, в конце концов, это может быть неправильный способ решения подобных проблем.Кажется, работает, хотя?
После долгих изгибов с командной строкой появляется общее решение, поэтому кажется, что оно может работать хотя бы частично, поэтому его можно использовать в основе решения, а затем использовать другие инструменты, такие как
awk
иsed
для его очистки. , Тем не менее, возникает вопрос: «Если вы убираете это с помощьюawk
&sed
любым способом, то вы могли бы просто использовать их напрямую?».источник
join
так что теперь в Интернете есть такой. 8-)Это должно быть возможно с помощью,
join
но я не могу понять, как заставить его печатать пробелы и пустые поля правильно. В любом случае, этот маленький скрипт на Perl сделает свое дело:Сохраните это как
foo.pl
и выполните следующее:источник
-o
функции раньше, не работает, как я ожидал.-o
и ,-e
но не мог заставить его печатать строки , которые не имели никаких записей в file2. Удачи, мне было бы интересно узнать, возможно ли это.Баш сделает.
Смотрите этот SO-ответ, чтобы узнать подробнее о том, что происходит с «хэшем». Bash 4 изначально поддерживает ассоциативный массив, но это должно работать в 3 + 4 (возможно, в 2?)
Возможно, вам придется обрезать строку из файла file1, чтобы получить форматирование.
источник
Вот простой способ сделать это
join
(+ еще пара инструментов) и сохранить интервал. Оба файла отсортированы по номеру станции, поэтому дополнительная сортировка не требуется:Часть перед каналом очень похожа на ту, что использовала slm в своем ответе, поэтому я не буду ее повторять. Единственное отличие состоит в том, что я использую
-e " "
- строку из четырех пробелов в качестве замены для пропущенных полей ввода и-o 2.2
для вывода только 2-го поля файла2.Таким образом,
join -j1 -a1 -o 2.2 -e " " file1 file2
создается столбец шириной в четыре символа (ниже он не виден, но после EK ничего нет ** и пустые строки на самом деле четыре пробела):Затем мы
paste
это (используя пробел в качестве разделителя) для file1, из которого мыcut
первые 5 символов| paste -d' ' - <(cut -c6- file1)
Конечный результат:
источник