一致しない行を含む、2つの列を持つ2つのファイルをそれぞれ関連付けます。

一致しない行を含む、2つの列を持つ2つのファイルをそれぞれ関連付けます。

ファイルごとに1つずつ、2つのソートされたデータセットを照合してマージしようとしています。各ファイルには、キーフィールドと関連値の2つの列が含まれています。生成される出力には、キーフィールド、最初のファイルの値(存在する場合)、および2番目のファイルの値(存在する場合)の3つの列を含める必要があります。一致しないデータ行を含める必要があります。

最初のファイル「ジョン」

apple,green
cherry,red
orange,orange

2番目のファイル「Jane」

apple,red
banana,yellow
cherry,yellow
kiwi,green

希望する結果

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

最初は、このことが私にとって面倒なことだと思った。join

LC_ALL=C join -j1 -a1 -a2 -t',' john jane

ただし、結果は常に-a1 -a22番目の列に一致しない値を入れます。

apple,green,red
banana,yellow
cherry,red,yellow
kiwi,green
orange,orange

理想的には、結果ファイルの適切な2番目または3番目の列にその値を配置することで、一致しない値がどのソースファイルに由来するかを判断できるはずですが、達成できる簡単な方法はわかりません。タイプ設定の詳細を知らなくても、これを行うことができますawk ... getline()

どんな提案がありますか?

答え1

あなたが望む-o auto

join -t, -j 1 -a 1 -a 2 -o auto john jane

~からman join:

-o FORMAT

    従うFORMAT出力ラインを設定するとき

︙もし      FORMATキーワードが ' auto' の場合、各ファイルの最初の行は各行に出力されるフィールドの数を決定します。

またはより良い説明GNU Coreutils: 呼び出しの追加 (リンクをクリックすると入ることができます。結合の一般オプション):

' -o auto'

" "キーワードを指定すると、auto出力形式は各ファイルの最初の行から推測されます。これは、デフォルトの出力形式と同じですが、行ごとに同じ数のフィールドが出力されることを保証します。不足しているフィールドはオプションに置き換えられ、-e重複フィールドは削除されます。

% cat john 
apple,green
cherry,red
orange,orange
% cat jane 
apple,red
banana,yellow
cherry,yellow
kiwi,green
% join -t, -j 1 -a 1 -a 2 -o auto john jane
apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

答え2

出力形式を明示的に指定できます。

LC_ALL=C join -o0,1.2,2.2 -j1 -a1 -a2 -t',' john jane

生産する

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

ここで重要なのは、結合フィールドを出力形式でも参照できることです0。これは、ペアリングできない行のコンテキストで役立ちます。

答え3

このコマンドはほぼ対応するタスクを実行します。キーがfile1にのみ表示される場合は、末尾のコンマは省略されます。今は完全にデバッグする時間がありません。

awk -F, 'BEGIN{OFS=","} FNR==NR{val[$1]=$2;next} {val[$1]=val[$1] "," $2}END{for (key in val) {print key, val[key]}}' john jane

出力:

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange

答え4

Rプログラミング言語の使用

2 つのデータファイルを R REPL に読み込みます。

> john <- read.csv("/Users/admin/john", header=FALSE, stringsAsFactors=FALSE)
> john
      V1     V2
1  apple  green
2 cherry    red
3 orange orange
>
> jane <- read.csv("/Users/admin/jane", header=FALSE, stringsAsFactors=FALSE)
> jane
      V1     V2
1  apple    red
2 banana yellow
3 cherry yellow
4   kiwi  green

R REPL でデータ・ファイルをマージするには、次のようにします。

> merge(john, jane, by = c("V1"), all=TRUE)
      V1   V2.x   V2.y
1  apple  green    red
2 banana   <NA> yellow
3 cherry    red yellow
4   kiwi   <NA>  green
5 orange orange   <NA>
> 

ファイルに出力(使用write.table):

> write.table( merge(john, jane, by = c("V1"), all=TRUE), "john_jane.csv", sep=",", quote=F, row.names=F, col.names=F, na="")

生成されたファイル( "john_jane.csv"):

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

パラメータが示すように、write.table<NA>値はを使用して空の文字列に設定されますna=""。追加のヘルプを表示するには、R REPLのプロンプトで、または?getwd()などの疑問符の前にコマンドを入力します?setwd()?read.csv()?merge()

[注:Rのインストール期間によっては、stringsAsFactors=FALSEすべての関数呼び出しにパラメータを含めることが重複することがあります。]read.csv()

https://www.r-project.org/
https://cran.r-project.org/index.html

関連情報