Предположим, что у меня есть два файла, en.csv
и sp.csv
, каждая из которых содержит ровно две разделенные запятыми записей:Как получить все поля во внешнем соединении с Unix?
en.csv
:
1,dog,red,car
3,cat,white,boat
sp.csv
:
2,conejo,gris,tren
3,gato,blanco,bote
Если я исполняю
join -t, -a 1 -a 2 -e MISSING en.csv sp.csv
выхода я получаю:
1,dog,red,car
2,conejo,gris,tren
3,cat,white,boat,gato,blanco,bote
Обратите внимание, что все недостающие поля были разрушились. Чтобы получить «правильное» полное внешнее соединение, мне нужно указать формат; Таким образом,
join -t, -a 1 -a 2 -e MISSING -o 0,1.2,1.3,1.4,2.2,2.3,2.4 en.csv sp.csv
дает
1,dog,red,car,MISSING,MISSING,MISSING
2,MISSING,MISSING,MISSING,conejo,gris,tren
3,cat,white,boat,gato,blanco,bote
Один недостаток этого способа для получения полного внешнего соединения является то, что нужно явно указать формат финального стола, который не может быть легко сделать в программном приложений (где идентификация соединенных таблиц известна только во время выполнения).
Последние версии GNU join
устраняют этот недостаток, поддерживая специальный формат auto
. Поэтому с такой версией join
последняя команда выше, может быть заменена гораздо более общей
join -t, -a 1 -a 2 -e MISSING -o auto en.csv sp.csv
Как я могу добиться этого же эффекта с версиями join
, которые не поддерживают опцию -o auto
?
фон и детали
У меня есть оболочка Unix (ЗШ) скрипт, который предназначен для процессов несколько flatfiles CSV, и делает это путем обширного использования GNU join
's' - o auto '. Мне нужно изменить этот сценарий, чтобы он мог работать в средах, где доступная команда join
не поддерживает опцию -o auto
(как в случае с BSD join
, так и для более старых версий GNU join
).
Типичное использование этого параметра в сценарии что-то вроде:
_reccut() {
cols="1,$1"
shift
in=$1
shift
if (($# > 0)); then
join -t, -a 1 -a 2 -e 'MISSING' -o auto \
<(cut -d, -f $cols $in | sort -t, -k1) \
<(_reccut "[email protected]")
else
cut -d, -f $cols $in | sort -t, -k1
fi
}
Я показываю этот пример, чтобы показать, что это было бы трудно заменить -o auto
с явной форме, так как поля для включения в этот формат не известен до выполнения.
Функция _reccut
выше в основном извлекает столбцы из файлов и соединяет результирующие таблицы вдоль их первого столбца.Чтобы увидеть, как _reccut
в действии, представьте себе, что, в дополнение к файлам, указанным выше, мы также имели файл
de.csv
2,Kaninchen,Grau,Zug
1,Hund,Rot,Auto
Тогда, например, для отображения бок о бок колонке 3 из en.csv
, столбцы 2 и 4 из sp.csv
и столбец 3 из de.csv один будет работать:
% _reccut 3 en.csv 2,4 sp.csv 3 de.csv | cut -d, 2-
red,MISSING,MISSING,Rot
MISSING,conejo,tren,Grau
white,gato,bote,MISSING
имея делать то, что вы говорите на 1-офф проекта с sun4, я думаю, что вы «застрял в кодировании своей собственной или поставлял новое GNU-соединение как часть вашей установки. Извините, но удачи. – shellter
Полагаю, я должен добавить, после долгих беспорядков, я закончил делать вспомогательные массивы в awk с гораздо меньшими проблемами. Удачи. – shellter