2つのファイルがen.csv
ありsp.csv
、それぞれにコンマで区切られた2つのレコードが含まれているとします。
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
完全な外部結合を生成するこの方法の1つの欠点は、ファイナルテーブルの形式を明示的に指定する必要があることです。これは、プログラムアプリケーション(結合されたテーブルのIDが実行時にのみ認識される)では簡単ではない場合があります。
最近のバージョンのGNUjoin
は、特別な形式をサポートすることでこの欠点を解消していますauto
。したがって、join
上記の最後のコマンドのそのようなバージョンでは、はるかに一般的なものに置き換えることができます
join -t, -a 1 -a 2 -e MISSING -o auto en.csv sp.csv
join
オプションをサポートしていないバージョンでこれと同じ効果をどのように達成でき-o auto
ますか?
背景と詳細
いくつかのCSVフラットファイルを処理するように設計されたUnixシェル(zsh)スクリプトがあり、GNUの「-oauto」オプションを多用することで処理します。join
このスクリプトを変更して、使用可能なjoin
コマンドがオプションをサポートしていない環境で機能するようにする必要があり-o auto
ます(BSDjoin
および古いバージョンの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 "$@" )
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
、およびde.csvの列3を並べて表示するには、次のように実行します。
% _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