अगर मेरे पास एक सीएसवी फ़ाइल है, तो क्या किसी एकल कॉलम की सामग्री को प्रिंट करने का एक त्वरित तरीका है? यह मान लेना सुरक्षित है कि प्रत्येक पंक्ति में समान स्तंभ हैं, लेकिन प्रत्येक स्तंभ की सामग्री की लंबाई अलग-अलग होगी।
अगर मेरे पास एक सीएसवी फ़ाइल है, तो क्या किसी एकल कॉलम की सामग्री को प्रिंट करने का एक त्वरित तरीका है? यह मान लेना सुरक्षित है कि प्रत्येक पंक्ति में समान स्तंभ हैं, लेकिन प्रत्येक स्तंभ की सामग्री की लंबाई अलग-अलग होगी।
जवाबों:
आप इसके लिए awk का उपयोग कर सकते हैं। Change $ 2 ’को अपने इच्छित nth कॉलम में बदलें।
awk -F "\"*,\"*" '{print $2}' textfile.csv
gawk -F"|" "{print $13}" files*.csv
...,"string,string",...
"
और आखिरी के साथ समाप्त होगा"
awk -F "\"*;\"*" '{print $2}' textfile.csv
हाँ। cat mycsv.csv | cut -d ',' -f3
3 कॉलम प्रिंट करेगा।
awk
सबसे आसान तरीका है कि मैं इसे पूरा करने में सक्षम था बस csvtool का उपयोग करें । मेरे पास अन्य उपयोग के मामले के साथ-साथ सीएसवेटूल का उपयोग करने के लिए भी था और यह कॉलम या सीमांकक को उचित रूप से संभाल सकता है यदि वे कॉलम डेटा के भीतर दिखाई देते हैं।
csvtool format '%(2)\n' input.csv
कॉलम नंबर के साथ 2 की जगह प्रभावी रूप से आपके द्वारा खोजे जा रहे कॉलम डेटा को निकाल देगा।
cat input.csv | csvtool formath '%(2)\n' -
नोट मुझे पता है कि बिल्ली यहां बेकार है, लेकिन इसे किसी भी कमांड के लिए उप है जो सामान्य रूप से सीएसवी निर्यात करेगा।
format '%(2)\n'
कमांड यह नहीं बता सकता कि एक फ़ील्ड कहाँ समाप्त होती है। (csvtool 1.4.2)
csvtool
उपयोग करने की आवश्यकता प्रतीत होती है -
।
csvtool format '%(1),%(10)\n' - < in.csv > out.csv
यहाँ एक अलग फ़ाइल से टैब निकालने की तलाश में। सोचा था कि जोड़ दूंगा।
cat textfile.tsv | cut -f2 -s
जहां -f2
2, गैर-शून्य अनुक्रमित स्तंभ, या दूसरा कॉलम निकालता है।
cat
अनावश्यक है:< textfile.tsv cut -f2 -s
इस प्रश्न के कई उत्तर महान हैं और कुछ ने तो कोने के मामलों में भी देखा है। मैं एक सरल उत्तर जोड़ना चाहूंगा जो दैनिक उपयोग का हो सकता है ... जहां आप ज्यादातर उन कोने के मामलों में आते हैं (जैसे कि उद्धरणों में अल्पविराम या अल्पविराम से बचना आदि)।
FS (फील्ड सेपरेटर) वह चर है जिसका मान अंतरिक्ष में dafaulted है। इसलिए किसी भी लाइन के लिए स्पेस में डिफॉल्ट स्प्लिट्स से जागना।
इसलिए BEGIN (इनपुट लेने से पहले Execute) का उपयोग करके हम इस क्षेत्र को अपनी इच्छानुसार कुछ भी सेट कर सकते हैं ...
awk 'BEGIN {FS = ","}; {print $3}'
उपरोक्त कोड csv फ़ाइल में 3rd कॉलम प्रिंट करेगा।
अन्य उत्तर अच्छी तरह से काम करते हैं, लेकिन चूंकि आपने बस बैश शेल का उपयोग करके समाधान के लिए कहा है, आप ऐसा कर सकते हैं:
AirBoxOmega:~ d$ cat > file #First we'll create a basic CSV
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
और फिर आप कॉलम को बाहर निकाल सकते हैं (इस उदाहरण में पहला) जैसे:
AirBoxOmega:~ d$ while IFS=, read -a csv_line;do echo "${csv_line[0]}";done < file
a
1
a
1
a
1
a
1
a
1
a
1
इसलिए यहां कुछ चीजें चल रही हैं:
while IFS=,
- यह IFS (आंतरिक क्षेत्र विभाजक) के रूप में अल्पविराम का उपयोग करने के लिए कह रहा है, जो कि शेल का उपयोग करता है यह जानने के लिए कि फ़ील्ड (पाठ के ब्लॉक) को अलग करता है। तो IFS = कह रहा है, "A, b" के समान है, "B a" जैसा होगा यदि IFS = "" होगा (जो कि डिफ़ॉल्ट रूप से यही है।)
read -a csv_line;
- यह कह रहा है कि प्रत्येक पंक्ति में पढ़ा जाता है, एक समय में एक और एक सरणी बनाएं जहां प्रत्येक तत्व को "csv_line" कहा जाता है और इसे लूप करते समय हमारे "अनुभाग" के लिए भेजें।
do echo "${csv_line[0]}";done < file
- अब हम "do" चरण में हैं, और हम सरणी के 0 वें तत्व "csv_line" को प्रतिध्वनित कर रहे हैं। यह क्रिया फ़ाइल की प्रत्येक पंक्ति पर दोहराई जाती है। < file
हिस्सा सिर्फ जहां से पढ़ने के लिए है, जबकि पाश कह रहा है। नोट: याद रखें, बाश में, सरणियाँ 0 अनुक्रमित हैं, इसलिए पहला स्तंभ 0 तत्व है।
तो वहाँ आप यह है, खोल में एक CSV से एक स्तंभ बाहर खींच। अन्य समाधान शायद अधिक व्यावहारिक हैं, लेकिन यह एक शुद्ध बैश है।
आप GNU Awk का उपयोग कर सकते हैं, उपयोगकर्ता गाइड के इस लेख को देखें । लेख में प्रस्तुत समाधान में सुधार के रूप में (जून 2015 में), निम्न गॉक कमांड दोहरे उद्धृत क्षेत्रों के अंदर दोहरे उद्धरण चिह्नों की अनुमति देता है; एक दोहरे उद्धरण को दो लगातार दोहरे उद्धरण चिह्नों ("") द्वारा चिह्नित किया जाता है। इसके अलावा, यह खाली फ़ील्ड की अनुमति देता है, लेकिन यहां तक कि यह मल्टीलाइन फ़ील्ड को संभाल नहीं सकता है । निम्न उदाहरण c=3
textfile.csv के तीसरे स्तंभ (के माध्यम से ) को प्रिंट करता है :
#!/bin/bash
gawk -- '
BEGIN{
FPAT="([^,\"]*)|(\"((\"\")*[^\"]*)*\")"
}
{
if (substr($c, 1, 1) == "\"") {
$c = substr($c, 2, length($c) - 2) # Get the text within the two quotes
gsub("\"\"", "\"", $c) # Normalize double quotes
}
print $c
}
' c=3 < <(dos2unix <textfile.csv)
ध्यान से dos2unix
संभव डॉस स्टाइल लाइन ब्रेक (CRLF यानी "\ r \ n") और UTF-16 एन्कोडिंग (बाइट ऑर्डर मार्क के साथ) को "\ n" और UTF-8 (बाइट ऑर्डर मार्क के बिना) के उपयोग पर ध्यान दें। मानक CSV फाइलें लाइन ब्रेक के रूप में CRLF का उपयोग करती हैं, विकिपीडिया देखें ।
यदि इनपुट में मल्टीलाइन फ़ील्ड हो सकते हैं, तो आप निम्न स्क्रिप्ट का उपयोग कर सकते हैं। आउटपुट में रिकॉर्ड को अलग करने के लिए विशेष स्ट्रिंग के उपयोग पर ध्यान दें (चूंकि डिफ़ॉल्ट विभाजक न्यूलाइन रिकॉर्ड के भीतर हो सकता है)। फिर से, निम्न उदाहरण c=3
textfile.csv के तीसरे कॉलम (के माध्यम से ) को प्रिंट करता है :
#!/bin/bash
gawk -- '
BEGIN{
RS="\0" # Read the whole input file as one record;
# assume there is no null character in input.
FS="" # Suppose this setting eases internal splitting work.
ORS="\n####\n" # Use a special output separator to show borders of a record.
}
{
nof=patsplit($0, a, /([^,"\n]*)|("(("")*[^"]*)*")/, seps)
field=0;
for (i=1; i<=nof; i++){
field++
if (field==c) {
if (substr(a[i], 1, 1) == "\"") {
a[i] = substr(a[i], 2, length(a[i]) - 2) # Get the text within
# the two quotes.
gsub(/""/, "\"", a[i]) # Normalize double quotes.
}
print a[i]
}
if (seps[i]!=",") field=0
}
}
' c=3 < <(dos2unix <textfile.csv)
समस्या का एक और तरीका है। csvquote एक CSV फ़ाइल की सामग्री को संशोधित कर सकता है ताकि क्षेत्र के भीतर विशेष वर्ण रूपांतरित हो जाएं ताकि कुछ कॉलम चुनने के लिए सामान्य रूप से यूनिक्स टेक्स्ट प्रोसेसिंग टूल का उपयोग किया जा सके। उदाहरण के लिए निम्नलिखित कोड तीसरा कॉलम आउटपुट करता है:
csvquote textfile.csv | cut -d ',' -f 3 | csvquote -u
csvquote
बड़ी फ़ाइलों को मनमाने ढंग से संसाधित करने के लिए इस्तेमाल किया जा सकता है।
यहां 2 कॉलम के साथ एक सीएसवी फ़ाइल उदाहरण है
myTooth.csv
Date,Tooth
2017-01-25,wisdom
2017-02-19,canine
2017-02-24,canine
2017-02-28,wisdom
पहला कॉलम पाने के लिए, उपयोग करें:
cut -d, -f1 myTooth.csv
f का मतलब फ़ील्ड है और d का मतलब सीमांकक है
उपरोक्त कमांड चलाने से निम्नलिखित आउटपुट उत्पन्न होंगे।
उत्पादन
Date
2017-01-25
2017-02-19
2017-02-24
2017-02-28
केवल दूसरा कॉलम पाने के लिए:
cut -d, -f2 myTooth.csv
और यहाँ आउटपुट आउटपुट है
Tooth
wisdom
canine
canine
wisdom
incisor
एक अन्य उपयोग मामला:
आपकी सीएसवी इनपुट फ़ाइल में 10 कॉलम होते हैं और आप कॉलम 2 को 5 और कॉलम 8 से, कॉमा को विभाजक के रूप में उपयोग करना चाहते हैं "।
विभाजकों को निर्दिष्ट करने के लिए कॉलम और -d (जिसका अर्थ "सीमांकक") निर्दिष्ट करने के लिए कट-ऑफ (जिसका अर्थ "फ़ील्ड") है। आपको बाद वाले को निर्दिष्ट करने की आवश्यकता है क्योंकि कुछ फाइलें स्तंभों को अलग करने के लिए रिक्त स्थान, टैब या कॉलोन का उपयोग कर सकती हैं।
cut -f 2-5,8 -d , myvalues.csv
कट एक कमांड उपयोगिता है और यहां कुछ और उदाहरण दिए गए हैं:
SYNOPSIS
cut -b list [-n] [file ...]
cut -c list [file ...]
cut -f list [-d delim] [-s] [file ...]
मुझे उचित CSV पार्सिंग की आवश्यकता थी, न कि cut
/ awk
और प्रार्थना की। मैं इस पर एक कोशिश कर रहा हूँ MAC बिना csvtool
, लेकिन macs माणिक के साथ आते हैं, तो आप कर सकते हैं:
echo "require 'csv'; CSV.read('new.csv').each {|data| puts data[34]}" | ruby
पहले हम एक बुनियादी CSV बनाएंगे
[dumb@one pts]$ cat > file
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
तब हमें 1st कॉलम मिलता है
[dumb@one pts]$ awk -F , '{print $1}' file
a
1
a
1
मुझे लगता है कि सबसे आसान csvkit का उपयोग कर रहा है :
दूसरा स्तंभ हो जाता है:
csvcut -c 2 file.csv
हालांकि, वहाँ भी csvtool है , और शायद वहाँ से बाहर अन्य csv bash उपकरण की एक संख्या है:
sudo apt-get install csvtool
(डेबियन आधारित प्रणालियों के लिए)
इससे पहली पंक्ति में एक कॉलम होगा जिसमें 'ID' होगा।
csvtool namedcol ID csv_file.csv
यह चौथी पंक्ति लौटाएगा:
csvtool col 4 csv_file.csv
यदि आप शीर्ष लेख पंक्ति को छोड़ना चाहते हैं:
csvtool col 4 csv_file.csv | sed '1d'
मुझे आश्चर्य है कि अब तक के जवाबों में से किसी ने भी csvkit का उल्लेख नहीं किया है।
सीएसवी के साथ कार्य करने और कार्य करने के लिए csvkit कमांड-लाइन टूल का एक सूट है
मैं इसे विशेष रूप से सीएसवी डेटा प्रबंधन के लिए उपयोग करता हूं और अभी तक मुझे ऐसी समस्या नहीं मिली है जिसे मैं cvskit का उपयोग करके हल नहीं कर सका।
Cvs फ़ाइल से एक या अधिक कॉलम निकालने के लिए आप उस csvcut
उपयोगिता का उपयोग कर सकते हैं जो टूलबॉक्स का हिस्सा है। दूसरे कॉलम को निकालने के लिए इस कमांड का उपयोग करें:
csvcut -c 2 filename_in.csv > filename_out.csv
अगर सीएसवी में तार उद्धृत किए जाते हैं, तो q
विकल्प के साथ उद्धरण वर्ण जोड़ें :
csvcut -q '"' -c 2 filename_in.csv > filename_out.csv
के साथ स्थापित करें pip install csvkit
या sudo apt install csvkit
।
आप इसे पूर्ण CSV पार्सर के बिना नहीं कर सकते।
cut
गिनती करता है?
कुछ समय के लिए इस कोड का उपयोग करते हुए, यह "त्वरित" नहीं है जब तक कि आप "स्टैकओवरफ़्लो से काटने और चिपकाने" की गिनती नहीं करते हैं।
यह IFS के बजाय लूप में $ {##} और $ {%%} ऑपरेटरों का उपयोग करता है। यह 'इरेट' और 'डाई' कहता है, और एसईपी चार्ट के रूप में केवल कॉमा, डैश और पाइप का समर्थन करता है (यह सब मुझे आवश्यक है)।
err() { echo "${0##*/}: Error:" "$@" >&2; }
die() { err "$@"; exit 1; }
# Return Nth field in a csv string, fields numbered starting with 1
csv_fldN() { fldN , "$1" "$2"; }
# Return Nth field in string of fields separated
# by SEP, fields numbered starting with 1
fldN() {
local me="fldN: "
local sep="$1"
local fldnum="$2"
local vals="$3"
case "$sep" in
-|,|\|) ;;
*) die "$me: arg1 sep: unsupported separator '$sep'" ;;
esac
case "$fldnum" in
[0-9]*) [ "$fldnum" -gt 0 ] || { err "$me: arg2 fldnum=$fldnum must be number greater or equal to 0."; return 1; } ;;
*) { err "$me: arg2 fldnum=$fldnum must be number"; return 1;} ;;
esac
[ -z "$vals" ] && err "$me: missing arg2 vals: list of '$sep' separated values" && return 1
fldnum=$(($fldnum - 1))
while [ $fldnum -gt 0 ] ; do
vals="${vals#*$sep}"
fldnum=$(($fldnum - 1))
done
echo ${vals%%$sep*}
}
उदाहरण:
$ CSVLINE="example,fields with whitespace,field3"
$ $ for fno in $(seq 3); do echo field$fno: $(csv_fldN $fno "$CSVLINE"); done
field1: example
field2: fields with whitespace
field3: field3
आप लूप करते समय भी उपयोग कर सकते हैं
IFS=,
while read name val; do
echo "............................"
echo Name: "$name"
done<itemlst.csv
echo '1,"2,3,4,5",6' | awk -F "\"*,\"*" '{print $2}'
के2
बजाय मुद्रित करेगा2,3,4,5
।