1つの.csvから別の.csvファイルに列を追加します


12

file1.csv

A,,C,D
A,,C,D
A,,C,D
A,,C,D

file2.csv

A,B
A,B
A,B
A,B

必要なOutput.csv

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D

「join」と「paste」を使用してみましたが、役に立ちませんでした。これを行うためのbashコマンドはありますか?列「A」は両方の.csvファイルで同じです。


それでは、列Bをファイル1にコピーするよう求めていますか?または、C列とD列をfile2にしますか?
ティム

どちらにしても、長い出力の一致「desiredOutput.csv」などとして罰金だろう
Roboman1723

他のすべての回答よりも簡単な新しい回答を追加しました(最初の回答が含まれています)。将来の参考のために情報を簡単に見つけられるように、それを受け入れることを検討したいかもしれません。
don.joey

回答:


11

awkコマンドのみで:

awk -F, '{getline f1 <"file2" ;print f1,$3,$4}' OFS=, file1

file1から行を取得してローカル変数f1に格納しf1、格納された行を出力し、最後にコンマで区切られたfile1からthird($3)およびforth($3)フィールドを,出力し、OFS(output field separator [space byデフォルト])をコンマ(,)に。


短いコマンドは次のようになります。

paste -d, file2 <(cut -d, -f3- file1)
 あいうえお  
 あいうえお  
 あいうえお  
 あいうえお  

file2を貼り付け、3番目の列を-f3-file1のnext()にカットアンドペーストします。


awkし、paste(オプションA)

以下のコマンドはC,D、file2の各行の最後にあるfile1から最後の2列()もコピーします。

paste -d',' file2  <(awk -F',' '{print $(NF-1)","$NF}' file1)

コマンド上記ペーストその後、(カンマ区切り文字を印刷するFILE2の内容を-d',')、その後(2つの最後のフィールドを貼り付けNF、最後のフィールドの指数であり、$NFそのインデックスがある文字列ですNF。だから、は、$(NF-1)最後のフィールドの前に2番目のフィールドである)ファイル1からのとき、これらの指標の再定義または、コンマspectator(-F',')で分割します。

awkし、paste(オプションB)

このコマンドは、(上記と同じである$3$4FILE1からの各ラインの第3及び第4のフィールドを指し):

paste -d',' file2  <(awk -F',' '{print $3","$4}' file1)

またはcutコマンドを使用した別のソリューション:

paste -d, <(cut -d, -f1 file1) <(cut -d, -f2 file2) <(cut -d, -f3- file1)

上記のコマンドのcutコマンドは、最初にfile1()から最初のフィールド(-f1カンマdelimiter(-d.)でインデックス付けされたcut -d, -f1 file1)を切り取り、次にfile2(cut -d, -f2 file2)の2番目のフィールドを切り取り、貼り付け、最後に3番目の列(-f3)をnexts(-)に切り取り、貼り付けますcut -d, -f3- file1再びfile1()から。

このコマンドも同じ結果を返します。

paste -d, <(awk -F',' '{print $1}' file1) <(awk -F',' '{print $2}' file2) <(awk -F',' '{print $3","$4}' file1)

file1(awk -F',' '{print $1}' file1)の2番目のフィールドを貼り付け、次にコンマ(-d,)を印刷してから、file2(awk -F',' '{print $2}' file2)の2番目の列を貼り付け、最後にfile1(awk -F',' '{print $3","$4}' file1)の2番目と最後の列を再度貼り付けます。


@kasiは、awk自体でこれを行うことができます。参照してくださいstackoverflow.com/a/14984673/3297613
のAvinashラジ

9

ここに美しさがあります(私は思う):

join -t, <(csvcut -c 1,3,4 file1.csv) <(csvcut -c 1,2 file2.csv)

手順ごとに分類:

手順1. csvkitをインストールします。

sudo pip install csvkit
sudo apt-get install python-dev python-pip python-setuptools build-essential

手順2.カンマを区切り文字として使用してjoinコマンドを使用する

join -t,

ステップ3.希望する実際の列をフィードします。それが実際に結合が実行される列であるため、最初の列に2回フィードする方法に注意してください(のデフォルトの動作join)。

join -t, <(csvcut --columns 1,3,4 file1.csv) <(csvcut --columns 1,2 file2.csv)

または略記:

join -t, <(csvcut -c 1,3,4 file1.csv) <(csvcut -c 1,2 file2.csv)

必要に応じて、その標準出力をファイル(desiredOutput)にリダイレクトできます。

長所

この方法には、提案されている他の方法に比べていくつかの利点があります。

何よりもまず、実際の結合を実行します。つまり、より複雑なデータにも使用できます。たとえば、別のフィールドで簡単に結合できます。フィールドの位置だけを見るのではなく、列を実際に考慮します。実際にはデータの形式(csv)で機能し、テキストのようには扱いません。

第二に、それは一つのコマンド(と表示統計情報)も、あなたがすることができます非常に強力なCSVツールキットを使用しcsvstats)、b)は(データがクリーンであるかどうかを確認してくださいcsvclean)、だけでなく、SQLに、JSONに変換し、あるいはにロードしますpython!このツールキットは、データ準備のためのデータサイエンスで頻繁に使用されます。


あなたがUbuntuでインストールしている場合は、csvkitをインストールする前に、Pythonの開発用ヘッダをインストールする必要がありますsudo apt-get install python-dev python-pip python-setuptools build-essential- リンク
カレル・

素晴らしい答えもあります。私は会社のサーバーで作業しているので、インストールには約1週間の書類作業が必要です。私のマシンでも動作します!
Roboman1723 14年

+1は、CSVデータ用の別のツールを見せてくれました。別の質問ですが、CSVデータファイル用のスタンドアロンレポートライターを知っていますか?
ジョー14年

@Joeは、「レポート作成者」について話すとき、あなたが何を意味するかについて、より具体的になることができますか?私はあなたが何を意味するのか理解していない。
don.joey


7

ここに別の美しいものがあります。これまでのすべての提案の中で最も簡単だと思います。

csvtool pastecol 2 2 file1.csv file2.csv

過去にcsvtoolをまだインストールしていない場合は、する必要がありsudo apt-get install csvtoolます。

ドキュメントから:

pastecol <column-spec1> <column-spec2> input.csv update.csv

ファイルinput.csvで参照される列のコンテンツを、update.csvで指定された対応する列のコンテンツに置き換えます。

例:

  csvtool pastecol 2-3 1- input.csv update.csv.csv > output.csv

この場合、ファイルの2番目の列を置き換える方法に注意してください。

file1.csv

A,,C,D
A,,C,D
A,,C,D
A,,C,D

file2.csv

A,B
A,B
A,B
A,B

2つのファイルを結合します。

csvtool pastecol 2 2 file1.csv file2.csv
A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D

基本的には、の2 file2.csv列目を2列目として貼り付けますfile1.csv

これは同じドキュメントでも機能することに注意してください。2つの列を交換する場合は、input.csvおよびupdate.vscと同じファイルを使用して交換できます。

csvtool pastecol 2 1 file2.csv file2.csv 
A,A
A,A
A,A 
A,A

間違いなく最もエレガント。
ジェイコブVlijm 14年

2

選択した数の列をあるファイルから別のファイルに移動するには:

#!/usr/bin/env python3

cols = 1; file_1 = "/path/to/file_1"; file_2 = "/path/to/file_2"

def readfile(file):
      with open(file) as src:
          return [item.strip().split(",") for item in src.readlines()]

file_1 = readfile(file_1); file_2 = readfile(file_2)

for i in range(len(file_1)):
    print((",").join(file_1[i]+file_2[i][-cols:]))

2つのファイルから:

file_1

A,B
A,B
A,B
A,B

file_2

K,L,M
K,L,M
K,L,M
K,L,M

設定するときcols = 1

A,B,M
A,B,M
A,B,M
A,B,M

ただし、設定する場合cols = 2

A,B,L,M
A,B,L,M
A,B,L,M
A,B,L,M

cols = 3

A,B,K,L,M
A,B,K,L,M
A,B,K,L,M
A,B,K,L,M

使い方

空のファイルにコピーし、パスを設定しfile1file2そして列数はそれとして保存、移動することmove.pyによって、それを実行します。

python3 /path/to/move.py

この方法で、ソースファイルの列の中央から1つ以上の列を追加することもできます。


あなたが使用してimport csvいるのを見たいと思っていました。
don.joey

@ don.joey提案をありがとう、間違いなく調べます。
ジェイコブVlijm 14年

0

csvモジュールを使用したPythonの別のメソッド。

script.py

#!/usr/bin/python3
import csv
import sys
file1 = sys.argv[1]
file2 = sys.argv[2]
with open(file2, 'r') as r:
    with open(file1, 'r') as f:
        csv_f = csv.reader(f)
        csv_r = csv.reader(r)
        bar = [linex for linex in csv_r]
        foo = [liney[2:] for liney in csv_f]
        zipped = zip(bar,foo)
        result = [x+y for (x,y) in list(zipped)]
        for i in result:
            print(','.join(i))

上記のスクリプトを実行するには、

python3 script.py file1 file2

出力:

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.