খালি লাইনগুলি সরানোর জন্য কোনও পাঠ্য ফাইল ফিল্টার করার ভাল উপায় কী?


11

আমার কাছে একটি .csv ফাইল আছে (একটি ম্যাকের উপরে) খালি লাইনের একটি গুচ্ছ রয়েছে, যেমন:

"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum 

lorem ipsum ","2","3","4"
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum 

lorem ipsum ","2","3","4"

যা আমি রূপান্তর করতে চাই:

"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum ","2","3","4"
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum  lorem ipsum ","2","3","4"

আমি জানি যে এখানে অবশ্যই একটি লাইনার থাকতে হবে তবে আমি জড়ান বা সেড জানি না। কোনও টিপস ব্যাপকভাবে প্রশংসা!


1
সেই নমুনা অনুসারে আপনি ক্ষেত্রগুলি থেকে এম্বেড করা লাইন ব্রেকগুলি সরাতে চান। এটা কি ঠিক? অন্য কথায়, 6 টি ইনপুট লাইন আছে এবং 2 আউটপুট লাইন হওয়া উচিত?
manatwork

হ্যাঁ, আমি ঠিক এটাই থেকে মুক্তি পাওয়ার চেষ্টা করছি: একটি উদ্ধৃত স্ট্রিংয়ের ভিতরে এম্বেড করা নিউলাইনগুলি।
পিটোসালাস

সুতরাং আপনার যা দরকার তা হ'ল উদ্ধৃতিগুলির ভিতরে থাকা নতুন লাইনগুলি সরিয়ে দেয়। এটি আরও জটিল হতে চলেছে, কারণ আপনার মাল্টলাইন রেজেক্স দরকার।
টঙ্গ্পু

উত্তর:


11

আপনি এটি করতে গ্রেপের -v(বিপরীত ম্যাচ) মোডটি ব্যবহার করতে পারেন :

grep -v '^$' old-file.csv > new-file.csv

নোট করুন যে শেলগুলি পুনঃনির্দেশগুলি কীভাবে কাজ করে সেগুলির জন্য সেগুলি আলাদা আলাদা ফাইল হওয়া দরকার। ইনপুট ফাইলটি পড়ার আগে আউটপুট ফাইলটি খোলা হয় (এবং খালি হয়)। আপনার যদি অতিরিক্ত উপকরণ (ম্যাক ওএস এক্সে ডিফল্টরূপে নয়) থাকে তবে আপনি এটি ব্যবহার করতে পারেন sponge:

grep -v '^$' file.csv | sponge file.csv

তবে অবশ্যই, আপনার যদি কিছু ভুল হয়ে যায় তবে ফিরে যেতে আপনার পক্ষে আরও শক্ত সময় হবে।

যদি আপনার "ফাঁকা লাইনগুলি" আসলে ফাঁকা স্থান ধারণ করে (মনে হয় তারা তাদের মতো করে) তবে তার পরিবর্তে আপনি এটি ব্যবহার করতে পারেন:

egrep -v '^[[:space:]]*$' old-file.csv > new-file.csv

এটি খালি রেখাগুলি পাশাপাশি কেবল শ্বেতস্থানযুক্ত লাইনগুলিকে উপেক্ষা করবে। আপনি অবশ্যই spongeএটিতে একই রূপান্তর করতে পারেন।


ধন্যবাদ .... কোনও খালি লাইন মুছে ফেলেনি ... সম্ভবত ^ matching মিলছে না? তবে লাইনগুলি আমার জ্ঞানের সেরাটি খালি। মনে রাখবেন এটি ম্যাকের উপরে এক্সেল দ্বারা নির্মিত একটি সিডিভি ... এটি কি কিছু বলে? (চিৎকার করে পালিয়ে যাবেন না কারণ আমি এক্সেল বলেছি :)
পিটোসালস

@ পিটোসালস তারা সম্ভবত খালি লাইন নয়। এটিকে egrep -v '^[[:space:]]*$'... নোট
গ্রেপ

কাজ হয়নি। একগুচ্ছ ডাবল উদ্ধৃতি মুছে ফেলা হয়েছে এবং একটি বিশৃঙ্খলা তৈরি করেছে ...
পিটোসালাস

@ পিতোসালাস আমি নিশ্চিত নই যে এটি কীভাবে ডাবল উদ্ধৃতি মুছবে। এটি কেবল সাদা স্থান মুছতে সক্ষম হবে। এবং প্রকৃতপক্ষে, এটি পোস্ট করে যখন আপনি পোস্ট করেছেন এমন উদাহরণের ডেটা পরীক্ষা করে ...
ডার্বার্ট

@ পিতোসালাস আপনি যাচাই করতে পারেন এই কমান্ডগুলির মধ্যে যে iconv -f utf16le file.csv | headiconv -f utf16be file.csv | head
কোনওটি

8

সবচেয়ে সহজ বিকল্পটি ন্যায্য grep .। এখানে, বিন্দুটির অর্থ "কোনও কিছুর সাথে মিল", সুতরাং লাইনটি খালি থাকলে এটি মেলে না। অন্যথায় এটি পুরো লাইনটি যেমন প্রিন্ট করে।


6

খালি লাইনগুলি সরিয়ে ফেলতে, জায়গায় ksh93 দিয়ে:

sed '/./!d' file 1<>; file

<>;ফেরৎ অপারেটর ksh93 নির্দিষ্ট এবং স্ট্যান্ডার্ড হিসাবে একই <>যে ksh কাটছাঁট করে কমান্ড পরে ফাইল স্থগিত করল ব্যতীত অপারেটর।

sed '/./!d'এটি লেখার একটি বিভ্রান্তিকর উপায় grep ., তবে দুর্ভাগ্যক্রমে GNU গ্রেপ কমপক্ষে অভিযোগ করে যদি এটির স্টডআউট তার স্টিডিনের মতো একই ফাইলটিতে নির্দেশ করে। আপনি বলবেন যে কেউ লিখতে পারে:

grep . file | cat 1<>; file

তবে দুর্ভাগ্যক্রমে, ksh93 এ একটি বাগ আছে (কমপক্ষে আমার সংস্করণ (93u +)), সেই ক্ষেত্রে ফাইলটি শূন্য দৈর্ঘ্যে ছিন্ন হয়ে গেছে বলে মনে হচ্ছে।

grep . file | { cat; } 1<>; file

এই বাগটির চারপাশে কাজ করার মতো মনে হচ্ছে তবে এখন এটি সেড কমান্ডের চেয়ে অনেক বেশি সংশ্লেষিত।


প্রতিটি সমাধান কখন ব্যবহার করা উচিত তার জন্য একটি দ্রুত গাইডের সাথে দয়া করে আপনার উত্তরগুলি একটি ভাল ফর্ম্যাট এন্ট্রিতে একত্রিত করুন। ভাসমান উত্তরে একসাথে ছড়িয়ে পড়ে বিভিন্ন সমস্যার বিভিন্ন পন্থা এই প্রশ্নটি পড়ার জন্য কিছুটা বিপর্যয় তৈরি করেছে make
কালেব

@ কালেব, এগুলি সমস্ত প্রশ্নটি খুব স্পষ্ট না হয়ে ফোটায়, সুতরাং প্রত্যেকের উত্তরই প্রশ্নের বিভিন্ন ব্যাখ্যা করার জন্য। প্রতিটি উত্তরের জন্য, আমি বলার চেষ্টা করেছি যে এটি কোন প্রশ্নের উত্তর দেওয়ার চেষ্টা করে।
স্টাফেন চেজেলাস

শুধু এফওয়াইআই: চেষ্টা করেছেন awk '/./' file 1<>; fileযা কাজ করেছে। আমার কাছে, এটি তার থেকেও পরিষ্কারsed '/./!d'
গ্র্যাঙ্ককে

5

Perlএটির জন্য এখানে একটি ওলাইনার রয়েছে:

perl -pi -e 's/^\s*\n//' yourfile

সম্পাদনা: নীচে রুখের মন্তব্যের ভিত্তিতে উন্নত কোড


1
বাperl -ni -e '/./ and print' yourfile
ডার্বার্ট

1
@ পিটারফ $একটি অ্যাঙ্কর (অর্থাত শূন্য-প্রস্থ) তাই এটি নতুন লাইনটি বাদ দেয়। অতিমাত্রায় স্থান হিসাবে, আমি যুক্ত করেছি কারণ আমি ge $ \ `কে রেজেক্সে অন্তর্ভুক্ত করার চেষ্টা /xকরতে চাইনিPerl
জোসেফ আর।

1
আপনার দরকার নেই $, প্রদত্ত যে আপনার কাছে রয়েছে \n। (বিকল্পভাবে - আপনার এবং \nআপনার কাছে থাকা \s*সত্ত্বেও আপনার দরকার নেই $; তবে আমি মনে করি s/^\s*\n//যে নতুন লাইনটি সরানো হয়েছে এটি আরও পরিষ্কার করে দেয়;) আপনারও দরকার নেই /m; এর এই আদেশের কোনও প্রভাব নেই। এবং একবার আপনি $স্থান এবং স্থান থেকে মুক্তি পেয়ে গেলে আপনার প্রয়োজন হবে না /x
রুখ

1
@ জোসেফআর: \nনিজেই সরানো যেতে পারে; তুমি কি করতে পার না সরান উভয় $ এবং\n । সুতরাং s/^\s*//সমস্যা আপনি বর্ণনা আছে, কিন্তু s/^\s*$//কারণ জরিমানা হবে, \s*এবং $। (আপনি কী বোঝাতে চাইছেন?)
রুখ

1
@ জোসেফআর: যা ঘটে তা একটি নতুন লাইনের আগে মেলাতে $ পারে (তবে শর্ত থাকে যে /mপতাকাটি সক্রিয় রয়েছে, অথবা নিউলাইনটি স্ট্রিংয়ের শেষ চরিত্র, বা উভয়ই) তবে এটি স্ট্রিংয়ের শেষের সাথেও মিলতে পারে । উদাহরণস্বরূপ, "abc" =~ m/^abc$/সত্য। ক্ষেত্রে \s*$, \s*লাইনটি নতুন লাইনটি খেয়ে যথেষ্ট লোভী এবং তারপরে $স্ট্রিং-এর সাথে ম্যাচগুলি মেলে। (তবে আমি মনে করি s/^\s*\n//যাই হোক, আরও স্পষ্ট, সুতরাং আপনার উত্তর এখনকার মতো ঠিক আছে))
রুখ

5

আপনার প্রশ্নের মন্তব্যে স্পষ্টতার ভিত্তিতে, এরকম কিছু:

awk -v RS= -v ORS= 1

আপনি যা চান তা করতে পারে

একটি খালি রেকর্ড বিভাজক একটি বিশেষ কেস যা awkরেকর্ডগুলি অনুচ্ছেদ হতে হবে (খালি রেখার ক্রম দ্বারা পৃথক) বলে। খালি স্ট্রিংয়ে আউটপুট রেকর্ড বিভাজক সেট করার অর্থ এই যে অনুচ্ছেদের সামগ্রীগুলি (বিভাজকগুলি ছাড়াই) একত্রিত করতে হবে। প্রতিটি রেকর্ড মুদ্রণের জন্য 1একটি সত্য শর্ত।

এটি তবে চলমান নতুন লাইনটি বাদ দিতে পারে, তাই আপনি এটি করতে পারেন:

awk -v RS= -v ORS= '1;END{if (NR) printf "\n"}'

3

আমি জানি আমি ফাইলটি দিলে এটি আরও সহজ হত, তবে দুর্ভাগ্যক্রমে এটিতে এমন গোপনীয় তথ্য রয়েছে যা আমি ভাগ করতে পারি নি। ইতিমধ্যে আমি আমাকে একটি রুবি স্ক্রিপ্ট লিখেছিলাম যা দেখে মনে হয় কৌশলটি করা হয়েছে:

require 'csv'
c = CSV.open("outfile1.csv", "w")
CSV.foreach("data.csv", :encoding => 'windows-1251:utf-8') do |row|
  row = row.map { |a| a.class == String ? a.gsub(/\r/, '') : a}
  c << row
end
c.close

সবাইকে সাহায্য করার জন্য ধন্যবাদ!


2
awk '
    length == 0 {next} 
    /^[^"]/ && /"$/ {print; next} 
    {printf("%s", $0)}
' filename

উত্পাদন করে

"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum ","2","3","4"
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum ","2","3","4"

2

আমি স্ট্যাকওভারফ্লোতে সম্ভাব্য সমাধানের জন্য একটি ধারণা পেয়েছি ।

sed -i ':a;N;$!ba;s/[^"]\n\s*\n/ /g' file.csv

আপনার সিএসভি ফাইলটি পরীক্ষা করার আগে সম্ভবত আপনার ব্যাকআপ করা উচিত, তবে কমপক্ষে আপনি যে উদাহরণটি দিয়েছেন তা নির্দোষভাবে কাজ করে।

এই অভিব্যক্তির অভ্যন্তরীণ কাজ সম্পর্কে একটি ভাল উত্তর উত্তরে দেওয়া হয়েছে, আমি কেবল এটি "( [^"]\n) দিয়ে শেষ না হওয়া লাইনের সন্ধানের জন্য এটি সম্পাদনা করেছি ।


1

যদি, আপনার নিজের প্রতিক্রিয়া থেকে, আপনি উদ্ধৃত স্ট্রিংগুলির মধ্যে থাকা নতুনরেখানের অক্ষরগুলি সরাতে চান, আপনি এটি করতে পারেন:

 perl -0777 -pe 's/".*?"/$_=$&;s:\n::g;$_/gse'

আপনি জায়গায়-i ফাইলগুলি সম্পাদনা করতে পার্লের পতাকা ব্যবহার করতে পারেন ।

 perl -0777 -pe 's/".*?"/$_=$&;s:\n::g;$_/gse' file1 file2...

বা জিএনইউ অ্যাজকের সাথে:

 awk -v RS=\" 'NR%2==0 {gsub("\n","")}; {printf "%s", $0 RT}'

বা:

 awk -vRS=\" '1-NR%2{gsub("\n","")}{ORS=RT}1'

(যদি আপনি সবচেয়ে কমের জন্য প্রতিযোগিতা করেন)

নোট করুন যেগুলি অনুমান করে যে ইনপুটটিতে কোনও পালানো ডাবল উদ্ধৃতি অক্ষর নেই।


0

এটি কার্যকরভাবে দেখে মনে হচ্ছে আপনি খালি লাইনগুলি মুছে ফেলার চেয়ে আরও কিছু চান তবে 2 বা ততোধিক নিউলাইন অক্ষরের প্রতিটি ক্রম সরিয়ে ফেলুন।

পার্ল দিয়ে আপনি যা করতে পারেন:

perl -0777 -pe 's/\n{2,}//gs' file

আপনি জায়গায়-i ফাইলগুলি সম্পাদনা করতে পার্লের পতাকা ব্যবহার করতে পারেন ।

perl -0777 -pi -e 's/\n{2,}//gs' file1 file2...

0

খালি লাইনগুলি মুছে ফেলার একটি দীর্ঘতম উপায় রয়েছে AWK:

awk 'NF' file

আপনি যে আউটপুটটি চান তা পেতে, একটি সহজ একটি লাইনার প্রয়োজন:

awk 'NF {printf("%s ", $0); i++;} !(i % 2) {printf("\n");}' file

ব্যাখ্যা

ইন AWK, একটি খালি রেখার অর্থ সারি / রেকর্ডের কোনও ক্ষেত্র নেই, অর্থাৎ NF(ক্ষেত্রের সংখ্যা) ভেরিয়েবল শূন্য। উপরের একটি লাইনার কেবল তখনই কার্যকর করা হবে যখন NF > 0সমস্ত লাইন মুদ্রণ করবে তবে খালি থাকবে।

i++খালি নয় এমন লাইন কাউন্টার হয়।

!(i % 2)আপনার পছন্দসই আউটপুট, যে পথে দুটি পরপর খালি নয় এমন লাইন প্রিন্ট করতে ব্যবহার করা হয়, প্রত্যেক সময় 2 এর গুণিতক পাওয়া যায়, moduloবিবৃতি !(i % 2)উৎপাদনের 1, দুটো খালি নয় এমন লাইন সংযুক্তকরণের বন্ধ।


আমার খারাপ! দুঃখিত। আমি তার পুরো প্রশ্ন এবং পছন্দসই আউটপুট পড়িনি। উত্তর এখন স্থির করা হয়েছে। ধন্যবাদ। :-)
মার্সেলো অগস্টো

0

আপনি প্রাক্তন মোডে ভিম ব্যবহার করতে পারেন:

ex -sc v/./d -cx b.csv
  1. v/./ খালি লাইন খুঁজে

  2. d মুছে ফেলা

  3. x সংরক্ষণ করেন এবং বন্ধ করেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.