Giả sử rằng tôi có hai tập tin, en.csv
và sp.csv
, mỗi chứa chính xác hai kỷ lục bằng dấu phẩy:Làm thế nào để có được tất cả các lĩnh vực bên ngoài tham gia với Unix tham gia?
en.csv
:
1,dog,red,car
3,cat,white,boat
sp.csv
:
2,conejo,gris,tren
3,gato,blanco,bote
Nếu tôi thực hiện
join -t, -a 1 -a 2 -e MISSING en.csv sp.csv
kết quả tôi nhận được là:
1,dog,red,car
2,conejo,gris,tren
3,cat,white,boat,gato,blanco,bote
Lưu ý rằng tất cả các trường bị thiếu đều bị thu gọn. Để có được một "bên ngoài" đầy đủ tham gia, tôi cần phải xác định một định dạng; do đó
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
mang
1,dog,red,car,MISSING,MISSING,MISSING
2,MISSING,MISSING,MISSING,conejo,gris,tren
3,cat,white,boat,gato,blanco,bote
Một nhược điểm của cách này để tạo ra một bên ngoài đầy đủ tham gia được rằng người ta cần phải xác định một cách rõ ràng các định dạng của bảng cuối cùng, mà có thể không được dễ dàng để làm trong chương trình các ứng dụng (trong đó danh tính của các bảng được nối kết chỉ được biết khi chạy).
Phiên bản gần đây của GNU join
loại bỏ thiếu sót này bằng cách hỗ trợ định dạng đặc biệt auto
. Do đó, với một phiên bản như vậy join
lệnh cuối cùng trên có thể được thay thế bằng xa tổng quát hơn
join -t, -a 1 -a 2 -e MISSING -o auto en.csv sp.csv
Làm thế nào tôi có thể đạt được hiệu ứng này tương tự với các phiên bản của join
không hỗ trợ tùy chọn -o auto
?
Bối cảnh và chi tiết
Tôi có một vỏ Unix (zsh) kịch bản được thiết kế để quá trình nhiều flatfiles CSV, và làm như vậy bằng cách làm cho rộng sử dụng GNU join
's' - o tự động 'tùy chọn. Tôi cần phải sửa đổi kịch bản này để nó có thể làm việc trong các môi trường nơi lệnh có sẵn join
không hỗ trợ tùy chọn -o auto
(như trường hợp cho BSD join
cũng như cho các phiên bản cũ hơn của GNU join
).
Một sử dụng điển hình của tùy chọn này trong kịch bản là một cái gì đó như:
_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
}
Tôi thấy ví dụ này để minh họa rằng nó sẽ rất khó để thay thế -o auto
với một định dạng rõ ràng, kể từ khi các lĩnh vực bao gồm trong này định dạng không được biết cho đến khi chạy.
Hàm _reccut
ở trên cơ bản trích xuất các cột từ tệp và tham gia các bảng kết quả dọc theo cột đầu tiên của chúng.Để xem cách _reccut
trong hành động, hãy tưởng tượng rằng, ngoài các tập tin đề cập ở trên, chúng tôi cũng có các tập tin
de.csv
2,Kaninchen,Grau,Zug
1,Hund,Rot,Auto
Sau đó, ví dụ, để hiển thị side-by-side cột 3 en.csv
, cột 2 và 4 của sp.csv
, và cột 3 của de.csv người ta sẽ chạy:
% _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
đã phải làm chính xác những gì bạn đang nói về một dự án 1-off với Sun4, tôi nghĩ bạn đang bị mắc kẹt với mã hóa của riêng bạn, hoặc cung cấp GNU mới tham gia như là một phần của cài đặt của bạn. Xin lỗi, nhưng may mắn. – shellter
Tôi đoán tôi nên thêm, sau khi rối tung nhiều xung quanh, tôi vết thương lên làm mảng assoc trong awk, với rắc rối ít hơn nhiều. Chúc may mắn. – shellter