एक फ़ाइल से डेटा निकालें और एक कॉलम मान के आधार पर अलग-अलग फ़ाइलों में रखें


14

हम नीचे मूल्यों के साथ एक सीएसवी फ़ाइल उत्पन्न करेंगे

yp1234,577,1,3
yp5678,577,3,5
yp9012,132,8,9

मुझे डेटा निकालने और दूसरे कॉलम के आधार पर फाइलें बनाने की आवश्यकता है। यदि यह 577 है, तो पूरी लाइन को अलग फ़ाइल में निकाला और रखा जाना है। मेरा मतलब है कि मुझे एक फाइल की जरूरत है जिसमें दूसरे कॉलम में ५ and another और दूसरी फाइल के साथ दूसरे कॉलम में १३२ अकेले हैं

मैंने IF का उपयोग करने की कोशिश की, लेकिन काम नहीं किया


5
वास्तव में काम नहीं करने वाले कोड को पोस्ट करना हमेशा एक अच्छा विचार होता है।
गोल्डीलॉक्स

जवाबों:


27

उपयोग करें awk:

awk -F, '{ print > $2 ".csv" }' file.csv

यह दो फ़ाइलें 577.csvऔर 132.csvआपकी वर्तमान निर्देशिका में बनाएगा ।

ऊपर दिया गया आदेश मानता है कि आप केवल 132या 577दूसरे क्षेत्र के रूप में हो सकते हैं । यह संपूर्ण के दूसरे क्षेत्र में पाए गए प्रत्येक मान के लिए एक फ़ाइल नाम बनाएगा file.csv

यदि आप में रुचि रखने वाले दो के अलावा अन्य मूल्य हैं, और आप उन पंक्तियों को अनदेखा करना चाहते हैं, तो इसके बजाय यह करें:

awk -F, '$2 == "577" || $2 == "132" { print > $2 ".csv" }' file.csv

1
वहाँ छोटी गाड़ी awkकार्यान्वयन है कि उपयोग नहीं कर सकते हैं print > $2 ".cvs"। उन पर आपको प्रथम गणना के लिए फ़ाइल नाम होता है, तो print: fname = $2 ".cvs"; print > fname
Kusalananda

3

मुझे टेर्डन का awkसमाधान पसंद है , लेकिन पूर्णता के लिए, यहां केवल सुझाव का उपयोग किया गया हैbash

while IFS=, read -r a1 a2 a3 a4; do 
    echo "$a1,$a2,$a3,$a4" >> "$a2".csv
done < file.csv

यह फ़ाइलों 577.csvऔर 132.csvवर्तमान निर्देशिका में उत्पादन करेगा ।


3

सभी 577 stdout करने के लिए निकालने के लिए

grep -e '^.*,577,.*,.*$' youfile.csv >result_extract_557.csv

577 के साथ लाइन पर कम से कम 3 कॉमा होने पर झूठे मैचों से बचने के लिए नीचे @ टेर्डन की टिप्पणी के आधार पर 1 सही संपादित करें।

grep -e '^[:alnum:]*,577,[:digit:]*,[:digit:]*$' youfile.csv >result_extract_557.csv

लेकिन मुझे लगता है कि उसका awkसमाधान अधिक व्यापक है।


अगर 577 दूसरे मैदान पर है तो भी मैच होगा, दूसरा नहीं या अगर यह किसी मैदान का हिस्सा है। उदाहरण के लिए foo577barया yp9012,132,8,577
terdon

मुझे लगा कि मेरा अल्पविराम इसे क्षेत्र की स्थिति पर निर्भर बना देगा?
एक्स तियान

क्षमा करें, मैंने बुरे उदाहरण दिए, लेकिन .*कॉमा से भी मेल खा सकते हैं ताकि आप यह न जान सकें कि आप किस क्षेत्र से मेल खा रहे हैं। दूसरा हो सकता है, 45 वां भी हो सकता है। मेरी दूसरी शिकायत गलत थी, आप सही कह रहे हैं कि कॉमा मिलान से बचाते हैं foo577bar
terdon

क्या करें अगर | के बजाय चरित्र का उपयोग किया जाता है।
user3116123 16

नीचे त्रुटि grep प्राप्त करना: अवैध विकल्प - e उपयोग: grep -hblcnsviw पैटर्न फ़ाइल। । ।
user3116123 16

1

का उपयोग कर csvkit:

$ csvgrep -c 2 -m 577 data.csv >output.csv

-c 2बनाता cvsgrepदूसरे स्तंभ पर विचार करें, और साथ -m 577हम स्ट्रिंग के मिलान से यह पूछना 577कि कॉलम में।

निम्नलिखित को लिखा जाएगा output.csv:

yp1234,577,1,3
yp5678,577,3,5

कई तार से मेल खाने के लिए और प्रत्येक स्ट्रिंग के लिए फ़ाइल में आउटपुट लिखें:

for pattern in 577 132; do
  csvgrep -c 2 -m "$pattern" data.csv >"output-$pattern.csv"
done

यह दो फ़ाइलों को बनाएगा output-132.csvऔर output-577.csv

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