मेरे पास वर्तमान में कई सीएसवी फाइलें हैं जहां मेरा इस पर कोई नियंत्रण नहीं है कि वे कैसे बनाए जाते हैं। कहने की जरूरत नहीं है... वे विकृत हैं और RFC 4180 के अनुरूप नहीं हैं।
उदाहरण इनपुट: gist
",0000000000000000";"0";"1115S021121-12-1/2"M"
",0000000000000000";"0";"1115S021122-12-1/2"M"
",0000000000000000";"0";"1115S021123-12-1/2"M"
",0000000000000000";"0";"1115S021124-12-1/2"M"
"1";"1";"EXAMPLE_RANDOM" . STRING"
"2,0000000000000000";"2";"this;can"also happen"
वांछित:
",0000000000000000";"0";"1115S021121-12-1/2""M"
मैं इसे रेगेक्स के साथ sed चलाकर इसे ठीक करने का प्रयास कर रहा हूं। हालाँकि मुझे केवल रेगेक्स का बुनियादी ज्ञान है और sed मेरे प्रयासों के साथ अच्छा नहीं खेलना चाहता।
क्या कोई मुझे दोहरे उद्धरण चिह्नों के अंदर इंच उद्धरण से बचने में मदद कर सकता है? मुझे पता है कि इस तरह के समाधान केवल 99% हैं, मैं केवल निम्नलिखित तथ्यों पर भरोसा कर सकता हूं।
- सीमांकक है;
- संलग्नक है"
- "उद्धृत टेक्स्ट फ़ील्ड में कई बार हो सकता है।
इसका मतलब है ए; या "उद्धृत फ़ील्ड में हो सकता है। क्या कोई मुझे "के साथ" को बदलने में मदद कर सकता है?
रेगेक्स पर मेरा प्रयास कई स्टैक ओवरफ्लो पोस्टों के संयोजन से है।
sed -E "s/[^\"](?<!;)\"(?!;|$)/\1"/g" $filename.test2 -> error
sed "s/[^\"](?<!;)(\")(?!;|$)/\1/g" $filename.test2 -> error
... about 10 more variations, some even without errors but no replaced strings.
अगर किसी के पास दूसरा समाधान है तो रेगेक्स, किसी भी मदद की बहुत सराहना की जाती है!
संपादित करें: @choroba पर्ल विज़ार्ड के लिए धन्यवाद। निम्नलिखित फ़ाइल को ठीक करता है।
cat $filename.test | perl -pe 's/(?<=[^;])"(?=[^;])/""/g' > $filename.test2
2 जवाब
पर्ल के आस-पास के पुनर्जीवन के दावे!
perl -pe 's/(?<=[^;])"(?=[^;\n])/""/g'
अर्थात। यदि कोई "
है जिसके पहले कोई ;
नहीं है और उसके बाद कोई ;
नहीं है, तो उसे ""
से बदल दें।
$ perl -MText::CSV_XS=csv -wE'csv(in=>csv(in=>"test.csv",sep=>";",allow_loose_quotes=>1,allow_loose_escapes=>1),always_quote=>1)'
",0000000000000000","0","1115S021121-12-1/2""M"
",0000000000000000","0","1115S021122-12-1/2""M"
",0000000000000000","0","1115S021123-12-1/2""M"
",0000000000000000","0","1115S021124-12-1/2""M"
"1","1","EXAMPLE_RANDOM"" . STRING"
"2,0000000000000000","2","this;can""also happen"
जैसा कि चोरोबा ने कहा, ";" के साथ आउटपुट सितंबर के रूप में भी:
$ perl -MText::CSV_XS=csv -wE'csv(in=>csv(in=>"test.csv",sep=>";",allow_loose_quotes=>1,allow_loose_escapes=>1),always_quote=>1,sep=>";")'
",0000000000000000";"0";"1115S021121-12-1/2""M"
",0000000000000000";"0";"1115S021122-12-1/2""M"
",0000000000000000";"0";"1115S021123-12-1/2""M"
",0000000000000000";"0";"1115S021124-12-1/2""M"
"1";"1";"EXAMPLE_RANDOM"" . STRING"
"2,0000000000000000";"2";"this;can""also happen"
अनुरोध द्वारा जोड़ा गया स्पष्टीकरण:
टेक्स्ट :: सीएसवी_एक्सएस एक पर्ल मॉड्यूल है जो सीएसवी को बहुत ही लचीले तरीके से पार्स और जेनरेट कर सकता है। गलत तरीके से फ़ॉर्मैट किए गए CSV को अनुमति देने के लिए विकल्पों/विशेषताओं का इस्तेमाल करना.
csv (in => "file.csv", ...) किसी फ़ाइल को आंतरिक संरचना में पढ़ता है
सितंबर => ";" विभाजक चरित्र को ";" पर सेट करता है डिफ़ॉल्ट "," के बजाय
allow_loose_quotes => 1 और allow_loose_escapes => 1 गलत सीएसवी को पढ़ना संभव बनाता है और अनचाहे नेस्टेड उद्धरणों को स्वीकार करता है
csv () आंतरिक संरचना का संदर्भ देता है, जो बाहरी csv कॉल के लिए मान्य है जो आउटपुट csv उत्पन्न करता है (in => csv (in => "file.csv")
अंतिम दो तर्क सितंबर को ";" पर सेट करते हैं आउटपुट के लिए भी और ओपी की आवश्यकता के अनुसार सभी फ़ील्ड को उद्धृत करने का कारण बनता है
सभी विकल्पों के लिए https://metacpan.org/module/Text::CSV_XS देखें और उदाहरण
एक स्क्रिप्ट में स्वरूपित, ऐसा लग सकता है
use Text::CSV_XS qw( csv );
csv ( # Outer function
always_quote => 1, # Quote all field
sep => ";", # Use ; instead of ,
in => # Input
csv ( # comes from inner function
in => "test.csv", # a file
sep => ";", # ; instead of ,
allow_loose_quotes => 1, # allow ,"foo"bar",
allow_loose_escapes => 1, # idem
)
);