21 сент. 2008 г.

Страсти по шеллу

Задача: есть два файла с экспортированными из базы таблицами (база — dbf, из-под мака работать не удобно). Нужно получить выборку со слиянием двух таблиц по заданной колонке.

1. Сортируем оба файла:
$ cat file.ext | sort -t $'\t' -k2,2 >file.sorted.ext
Здесь мы отсортировали файл с колонками, разделёнными табуляцией по второму столбцу. Сортировать оба файла надо по столбцу, в котором находится ключ.

Особенности:

1.1. Чтобы передать из bash'а в командной строке табуляцию, нужно использовать экранирование по стандарту ANSI C: [CTRL+V][TAB].

1.2. Sort не работает с юникодом, если LC_LOCALE не C. Проверяем так:
$ locale
LANG="ru_RU.UTF-8"
LC_COLLATE="C"
LC_CTYPE="C"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL="C"
Если нужно делаем
$ export LC_COLLATE=C
Замечаем, что less не выводит русские буквы если LC_* не русские.

2. Объединяем данные:
$ join -t $'\t' -o 1.1,2.2 -1 2 -2 1 file1.ext file2.ext >join.ext
Здесь мы выводим объединённые данные для двух файлов со столбцами, разделёнными табуляцией. Выводим первый столбец из первого файла и второй из второго. Ведём слияние по второму столбцу первого файла и первому столбцу второго (там должны быть одинаковые данные).

Замечаем, что:

2.1. Join НЕ работает если ключевая колонка не отсортирована (или отсортирована в обратном порядке) хотя бы в одном файле.

Комментариев нет: