एक .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

वांछित आउटपुट .csv

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

मैंने बिना किसी लाभ के "जॉइन" और "पेस्ट" का उपयोग करने की कोशिश की है। क्या ऐसा करने के लिए बैश कमांड है? कॉलम "ए" दोनों .csvफाइलों में समान है ।


तो आप कॉलम B से फाइल 1 को कॉपी करने के लिए कह रहे हैं? या फाइल 2 के लिए सी और डी कॉलम?
टिम

किसी भी तरह से तब तक ठीक रहेगा जब तक आउटपुट "वांछित ऑउटपुट" एससीवी से मेल नहीं खाता है
रोबोमेन 1723

मैंने एक नया उत्तर जोड़ा है, जो मुझे लगता है कि अन्य सभी उत्तरों की तुलना में आसान है (मेरा पहला उत्तर शामिल है)। आप इसे स्वीकार करने पर विचार कर सकते हैं ताकि भविष्य के संदर्भ के लिए जानकारी आसानी से मिल जाए।
don.joey

जवाबों:


11

केवल awkआदेश के साथ :

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

फ़ाइल 1 से एक रेखा प्राप्त करें और इसे स्थानीय चर में संग्रहीत करें f1, फिर उस लाइन को प्रिंट करें जो f1अंत में संग्रहीत है और फ़ाइल 1 से तीसरे ( $3) और आगे ( $3) फ़ील्ड प्रिंट करें जो अल्पविराम से ,पूरी तरह से सीमांकित है , और ओएफएस (आउटपुट फ़ील्ड सेपरेटर) को बदलकर डिफ़ॉल्ट]) अल्पविराम ( ,)।


संक्षिप्त आदेश इस तरह होगा:

paste -d, file2 <(cut -d, -f3- file1)
 ऐ बी सी डी  
 ऐ बी सी डी  
 ऐ बी सी डी  
 ऐ बी सी डी  

फ़ाइल 2 पेस्ट करें, फिर फ़ाइल 1 से तीसरे कॉलम को अगले ( -f3-) में काटें और चिपकाएँ ।


साथ awkऔर paste(विकल्प A)

नीचे दिए गए आदेश भी C,Dfile2 में प्रत्येक पंक्ति के अंत में file1 से अंतिम दो कॉलम ( ) की प्रतिलिपि बनाता है :

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

ऊपर कमांड फाइल 2 कंटेंट को पेस्ट करती है, फिर एक कॉमा सीमांकक ( -d',') प्रिंट करती है, फिर दो अंतिम फ़ील्ड को पेस्ट करती है (अंतिम फ़ील्ड NFका इंडेक्स है और $NFयह वह स्ट्रिंग है, जिसका इंडेक्स है NF। तो $(NF-1)फाइल इंडेक्स 1 से फाइल 1 में से दूसरा फ़ील्ड तब होता है)। या अल्पविराम दर्शक ( -F',') के साथ विभाजन ।

साथ awkऔर paste(विकल्प B)

यह कमांड भी ऊपर के समान है ( $3और $4फ़ाइल 1 से प्रत्येक पंक्ति के तीसरे और आगे के क्षेत्र को इंगित करता है):

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

या cutकमांड के साथ एक और समाधान :

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

कटौती उपरोक्त आदेश में आदेश पहले पहले क्षेत्र (कटौती -f1जो अल्पविराम सीमांकक (साथ अनुक्रमित -d.file1 (से)) cut -d, -f1 file1), तो कट जाता है और करें 2 (के दूसरे क्षेत्र पेस्ट cut -d, -f2 file2) और अंत में कटौती और तीसरे स्तंभ (पेस्ट -f3) nexts करने के लिए ( -) file1 ( cut -d, -f3- file1) से फिर।

यह आदेश भी वही परिणाम देता है:

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

awk -F',' '{print $1}' file1फ़ाइल 1 से दूसरे फ़ील्ड को पेस्ट करें ( ) फिर कॉमा ( -d,) प्रिंट करें , फिर फाइल 2 ( awk -F',' '{print $2}' file2) से दूसरा कॉलम पेस्ट करें, आखिर में फाइल 1 ( ) के दूसरे और आखिरी कॉलम को awk -F',' '{print $3","$4}' file1फिर से पेस्ट करें।


@ कासी आप खुद जागकर ऐसा कर सकती हैं। देखें stackoverflow.com/a/14984673/3297613
अविनाश राज

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 -t,

चरण 3. इसे वास्तविक कॉलम को फ़ीड करें जिसे आप चाहते हैं। ध्यान दें कि आप इसे पहले कॉलम को दो बार कैसे खिलाते हैं, क्योंकि वह वही है जो वास्तव में शामिल होता है (डिफ़ॉल्ट व्यवहार 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)

यदि आप चाहते हैं कि मानक आउटपुट को फ़ाइल (वांछित) में पुनर्निर्देशित कर सकते हैं।

लाभ

इस विधि में प्रस्तावित दूसरों की तुलना में कई फायदे हैं।

सबसे पहले और सबसे महत्वपूर्ण: यह एक वास्तविक जुड़ाव करता है। इसका मतलब है कि इसका उपयोग अधिक जटिल डेटा के लिए भी किया जा सकता है। उदाहरण के लिए, किसी अन्य फ़ील्ड में शामिल होना बहुत आसान है। यह केवल क्षेत्र की स्थिति को नहीं देखता है, लेकिन यह वास्तव में कॉलम को ध्यान में रखता है। यह वास्तव में डेटा (सीएसवी) के प्रारूप के साथ काम करता है और इसे पाठ की तरह व्यवहार नहीं करता है।

दूसरा, यह बहुत शक्तिशाली सीएसवी टूलकिट का उपयोग करता है जो आपको एक) एक कमांड ( csvstats), बी) के साथ आंकड़े प्रदर्शित करने की अनुमति देता है कि क्या डेटा साफ है ( csvclean), लेकिन इसे जौन में बदलने के लिए, या इसे लोड करने में भी। अजगर! यह टूलकिट डेटा विज्ञान में डेटा तैयारी के लिए भारी उपयोग किया जाता है।


यदि आप उबंटू में स्थापित कर रहे हैं, तो आपको csvkit को स्थापित करने से पहले पायथन विकास शीर्षकों को स्थापित करने की आवश्यकता हो सकती है: sudo apt-get install python-dev python-pip python-setuptools build-essential- लिंक
karel

के रूप में अच्छी तरह से जवाब, मैं एक कंपनी सर्वर पर काम कर रहा हूँ ताकि सामान स्थापित करने में लगभग एक सप्ताह का काम हो। हालांकि मेरी मशीन पर काम करता है!
रोबोमेन 1723

CSV डेटा के लिए मुझे दूसरा टूल दिखाने के लिए +1। अलग प्रश्न, लेकिन क्या आप CSV डेटा फ़ाइलों के लिए एक स्टैंडअलोन रिपोर्ट लेखक के बारे में जानते हैं?
जो

@ जो आप 'रिपोर्ट राइटर' के बारे में बोलते हैं, क्या आप इसके बारे में अधिक विशिष्ट हो सकते हैं? मुझे यकीन नहीं है कि मैं समझ सकता हूं कि आपका क्या मतलब है।
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 द्वारा संदर्भित कॉलम की सामग्री को अद्यतन में निर्दिष्ट कॉलम में से किसी एक के साथ बदलें ।csv।

उदाहरण:

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

ध्यान दें कि हमारे मामले में हम फ़ाइलों के दूसरे कॉलम को कैसे बदल रहे हैं।

उदाहरण

file1.csv

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

file2.csv

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

दो फाइलों को मिलाकर:

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

आप अनिवार्य file2.csvरूप से कॉलम 2 को कॉलम 2 के रूप में पेस्ट करते हैं file1.csv

ध्यान दें कि यह भी उसी दस्तावेज़ पर काम करता है। यदि आप दो कॉलम स्वैप करना चाहते हैं, तो आप उसी फाइल का उपयोग करके कर सकते हैं जैसे input.csv और update.vsc।

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

कोई संदेह नहीं कि सबसे सुरुचिपूर्ण।
जैकब व्लिजम

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:]))

दो फाइलों से:

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

कैसे इस्तेमाल करे

एक खाली फ़ाइल में कॉपी, करने के लिए पथ सेट file1, file2और स्तंभों की संख्या के रूप में सहेज ले जाते हैं, करने के लिए move.pyऔर से इसे चलाने:

python3 /path/to/move.py

स्रोत फ़ाइल के कॉलम्स के मध्य से इस तरह से एक या एक से अधिक कॉलम जोड़ना संभव है।


आप का उपयोग करते हुए देखने के लिए प्यार होता import csv
डॉन.जोए

@ don.joey सुझाव के लिए धन्यवाद, निश्चित रूप से इस पर गौर करेंगे।
याकूब Vlijm

0

सीएसवी मॉड्यूल के माध्यम से अजगर में एक और विधि।

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.