両方のファイルの列を結合して別々の出力ファイルに分割します。

両方のファイルの列を結合して別々の出力ファイルに分割します。

次のように、同じ最初の列と最初の行(ヘッダー)を共有する2つの大きなcsvファイルがあります。 etc は、同じパターンを持つより多くの値を意味します。

ファイル1.csv

names,text1,text2,text3,etc
A,1,4,3 ...
B,5,2,8 ...
C,3,7,4 ...
D,9,1,3 ...
etc

ファイル2.csv

names,text1,test2,text3,etc
A,7,2,9 ...
B,3,0,6 ...
C,8,7,2 ...
D,1,5,6 ...
etc

file1.csvとfile2.csvの列(一致するヘッダーまたは列番号を含む)とfile1.csvの最初の列を組み合わせて、ヘッダーの中間に基づいて名前付きの新しいファイルに出力するコード/スクリプトが必要です。

したがって、以下の出力ファイルなどが提供されます。

テキスト1.csv

names,text1,text1
A,1,7
B,5,3
C,3,8
D,9,1
etc

テキスト2.csv

names,text2,text2
A,4,2
B,2,0
C,7,7
D,1,5
etc

テキスト3.csv

names,text3,text3
A,3,9
B,8,6
C,4,2
D,3,6
etc

答え1

例に従って、両方のファイルがソートされていると仮定すると(ヘッダー行を除く)、次のことが機能します。

column=2
until [[ $column > $(awk -F, '{ print NF; exit }' file1.csv) ]] ; do 
  join -t , -o 1.1,1.$column,2.$column file1.csv file2.csv > $(awk -F, '{ print $'$column'; exit }' file1.csv).csv 
  ((column++))
done

(彫刻を借りました。@ヤノス存在するこの返信.)

ここで、ほとんどの魔法はjoin次のように実行されます。出力ファイルは現在のディレクトリに書き込まれます。

答え2

これは次のようになります。ミゲル・スビエラの答えしかし、Bashを使用して列数を計算し、ヘッダーを取得します。

IFS=, read -a headers < file1.csv
column=0
for h in "${headers[@]}"
do
        if [ "$((++column))" = 1 ]
        then
                continue
        fi
        join -t, -o "0,1.$column,2.$column" file1.csv file2.csv > "$h".csv
done

出力:

テキスト1.csv

names,text1,text1
A,1,7
B,5,3
C,3,8
D,9,1

テキスト2.csv

names,text2,test2
A,4,2
B,2,0
C,7,7
D,1,5

テキスト3.csv

names,text3,text3
A,3,9
B,8,6
C,4,2
D,3,6

メモ:

  • read -aファイルの最初の行を配列として読み込みます。
  • このcolumn変数の値は1、2、3、4、...です。 1の場合、出力ファイルはcolumn生成されないため処理されません。names.csv
  • データ列の場合、を実行すると、join最初の列(デフォルト)を連結してその列とcolumn各ファイルの数値列を出力します。この部分はほぼ似ています。ミゲル・スビエラの答え
  • headers配列(つまり、最初の行のフィールド)を使用してfile1.csv出力ファイルの名前を指定します。

そしてミゲル・スビエラの答えそしてルディックの答え、これは仮定

  • ファイルの列数は同じです(理想的には一致する必要があります)。
  • ファイル内の行(行)の数は同じです(一致する必要もあります)。

これは、ファイルがソートされている場合に最適ですが、ソートされていない場合でも機能します。内部に同じ注文する)。繰り返しますが、これはBashで実行する必要があります。

答え3

また試み

join -t, --header  file[12] | awk -F, -vOFS=, '
        {D = (NF-1)/2
         for (i=2; i<=D+1; i++) {if (FNR==1) FN[i] = $i
                                 print $1, $i, $(i+D)  >  FN[i] ".csv"
                                }
        }
'
cf te*

---------- text1.csv: ----------

names,text1,text1
A,1,7
B,5,3
C,3,8
D,9,1

---------- text2.csv: ----------

names,text2,test2
A,4,2
B,2,0
C,7,7
D,1,5

---------- text3.csv: ----------

names,text3,text3
A,3 ...,9 ...
B,8 ...,6 ...
C,4 ...,2 ...
D,3 ...,6 ...

これは、行とフィールドの数が同じ入力ファイルによって異なるため、そのセクションがjoin正しく完了し(--headerオプションを提供すると仮定して)、awk繰り返し回数を計算できます。その後、フィールドを繰り返して関連ファイルに印刷します。そのファイルの名前は最初の行に取り込まれます。

答え4

awk -F "," 'NR==FNR{a[FNR]=$2;b[$1]++;next}($1 in b){print $1,a[FNR],$2}' file1 file2

出力

file1
names text1 text1
A 1 7
B 5 3
C 3 8
D 9 1
awk -F "," 'NR==FNR{a[FNR]=$3;b[$1]++;next}($1 in b){print $1,a[FNR],$3}' file1 file2

出力

file2
names text2 test2
A 4 2
B 2 0
C 7 7
D 1 5
 awk -F "," 'NR==FNR{a[FNR]=$4;b[$1]++;next}($1 in b){print $1,a[FNR],$4}' file1 file2

出力

file3
names text3 text3
A 3  9
B 8 6
C 4 2
D 3 6

関連情報