গ্রেপ সাথে 0 দিয়ে রেখাটি সরান কিন্তু 0.2 নয়?


12

আমার একটি ফাইল রয়েছে যার বিষয়বস্তু নীচের মতো similar

0
0
0.2
0
0
0
0

আমার একক শূন্যের সাথে সমস্ত লাইন সরিয়ে ফেলতে হবে।
আমি ব্যবহার করার কথা ভাবছিলাম grep -v "0", তবে এটি 0.2 টি সমেত লাইনটিও সরিয়ে দেয়। আমি দেখেছি আমি -wবিকল্পটি ব্যবহার করতে পারি , তবে এটিও কার্যকর হবে বলে মনে হচ্ছে না।

আমি কীভাবে কেবল একটি একক 0 যুক্ত সমস্ত লাইন সরিয়ে ফেলতে পারি এবং সেই সমস্ত লাইন 0 দিয়ে শুরু করতে পারি?



1
@ জুলিয়েন লোপেজ এটি প্রশ্নটির একটি ধাপ নয়। এই প্রশ্নটি একটি শব্দের সাথে মিলে যায় এবং এর উত্তর দেওয়া হয় -wযা এখানে ব্যর্থ।
স্পারহক

আপনি grepএই কাজের জন্য ব্যবহার করতে বাধ্য হন কেন ? এবং একক শূন্যের অর্থ কী ? এটি খুব বেশি XY সমস্যার মতো মনে হচ্ছে ।
রোল্যান্ড ইলিগ

1
@ রোল্যান্ডইলিগ এটি শোবার আগে 1 ঘন্টা আগে ছিল এবং আমি চেয়েছিলাম 500,000 স্ট্রিংয়ের একটি সিরিজ প্রক্রিয়া শুরু করতে চাই যে তারা বিটকয়েন ব্যক্তিগত কীগুলি আছে কিনা এবং যদি ভারসাম্য পান তবে তা পরীক্ষা করতে পারেন। পরের বার আমার এটি দেখার সময় হয়েছিল আমি কয়েক হাজার স্ট্রিং প্রসেস করেছিলাম এবং আমি কেবল কোনও শূন্য-মানগুলির বিশ্লেষণ করতে চেয়েছিলাম।
ফিলিপ কির্কব্রাইড

উত্তর:


35
grep -vx 0

থেকে man grep:

-x, --line-regexp
       Select only those matches that exactly match the whole line.
       For a regular expression pattern, this is like parenthesizing
       the pattern and then surrounding it with ^ and $.

-wকারণ প্রথম ব্যর্থ 0মধ্যে 0.02একটি "শব্দ" হিসেবে গণ্য করা হয়, তাই এই লাইন মিলেছে করা হয়। এটি কারণ এটি একটি "শব্দহীন" চরিত্র দ্বারা অনুসরণ করা হয়। আপনি এই যদি তোমাকে ছাড়া মূল কমান্ডটি প্রয়োগ দেখতে পারেন -vঅর্থাত, grep -w "0"


আপনি -F
অপশনটিও

@glennjackman হয়তো আমি এটি আগে পড়েছি, তবে এখনই এটি খুঁজে পাবে বলে মনে হচ্ছে না। সঙ্গে চললে -F(আমার কাছে আশ্চর্যজনক) সময় একটি অনুরূপ পরিমাণ বা এমনকি কিছুটা মন্থর (~ 5-10%) নিতে বলে মনে হচ্ছে। অতএব, সুবিধাটি কী হবে তা আমি নিশ্চিত নই।
স্পারহাক

2
এটি সম্ভবত সম্ভব যে রেজিএক্স ইঞ্জিনটি প্রায়শই এবং এত ব্যাপকভাবে ব্যবহৃত হয় যে তারা এর একটি খুব দক্ষ সংস্করণ প্রয়োগ করেছে, তবে সম্ভবত একটি "সাধারণ অনুসন্ধান" 30 বছর ধরে আপগ্রেড করা হয়নি।
নেলসন

@ স্পারহাক: grepসম্ভবতঃ কোনও মেটাচার্যাক্টরবিহীন রেগেক্সদের জন্য একটি বিশেষ মামলা রয়েছে, কারণ এটি সাধারণ ব্যবহারের ক্ষেত্রে। এটি আশ্চর্যজনক যে fgrepধীর হতে পারে, তবে এটি আশ্চর্যজনক নয় যে একটি ছোট প্যাটার্নটি সংকলন করার সময় এই বিশেষ কেসটি লক্ষ্য করার ওভারহেডটি খুব বড় ফাইল স্ক্যান করার সময় তুলনামূলকভাবে কম। (দ্রুত গতিতে এগিয়ে যাওয়ার জন্য যদি কোনও বিশেষ ক্ষেত্রে প্রয়োজন হয় তবে বনাম একটি চরিত্রের শ্রেণীর সাথে একটি প্যাটার্ন বা x.*y))
পিটার কর্ডেস

তবে এটি সম্ভবত একটি ওভারসিম্প্লিফিকেশন কারণ ইনপুটটি আসলে অনেকগুলি ছোট লাইন (একটি দৈত্য স্ট্রিং নয়)। লাইন বিভাজক হিসাবে নিউলাইন grepছাড়া অন্য কোনও চরিত্রকে স্বীকৃতি দিলে আমি ভুলে গিয়েছি \n। যদি তা না হয় তবে অন্তর্নিহিত ^এবং $ এখনও স্থির স্ট্রিং অনুসন্ধানের মতো রূপান্তর করতে পারে strstr(big_buf, "\n0\n")। (বা 0\nএকটি বাফারের শুরুতে)) তবে আমরা কেবল প্রথম ম্যাচটি সম্ভবত একটি বড় বাফারের মধ্যে খুঁজছি না, আমরা দক্ষতার সাথে ফিল্টার করতে চাই। তবে যাইহোক, তত্ত্বের ক্ষেত্রে হ্যাঁ এটি প্রতিটি লাইনের শুরুতে কেবল একটি 2-বাইট মেমপ্যাম্প, এবং আপনি আশা করেন যে fgrep এবং গ্রেপ উভয়ই এটি দেখতে পাবে।
পিটার

28

গ্রেপ সহ:

grep -v "^0$" file

^এর অর্থ রেখার শুরু, $মানে রেখার শেষ।


2
ব্যবহারকারী এটির জন্যই বলেছিল: কেবলমাত্র "" 0 "ধারণকারী কোনও লাইন এড়িয়ে চলুন।
অলিভিয়ার ডুলাক

1
আমি এর মতো ডাবল কোটের ভিতরে একটি আক্ষরিক ডলার চিহ্ন রাখব না।
ব্যবহারকারী541686

@ মেহরদাদ রেগেক্সের সাথে এত বড় সমস্যা নয় কারণ এটি সাধারণত শেষ চর বা পরেরটি হয় না[a-Z0-9]
সাম্পো সরালালা - কোডিড্যাক্ট.org

14

যদিও এর জন্য ব্যবহার করা grep যেতে পারে (অন্যান্য উত্তরগুলি স্পষ্টভাবে দেখায়), আসুন আমরা একটি পদক্ষেপ নিয়ে আসি এবং আপনি আসলে কী চান তা নিয়ে ভাবি:

  • আপনি সম্বলিত একটি ফাইল আছে সংখ্যার
  • আপনি সংখ্যার মানের উপর ভিত্তি করে ফিল্টারিং সম্পাদন করতে চান ।

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

grepএখানে ব্যবহারের খুব ভাল কারণ না থাকলে (যেমন আপনি এটি পরিমাপ করেছেন এবং এটি আরও বেশি দক্ষ এবং আপনার ক্ষেত্রে দক্ষতা অত্যন্ত গুরুত্বপূর্ণ), আমি অন্য কোনও সরঞ্জাম ব্যবহার করার পরামর্শ দিই।

awkউদাহরণস্বরূপ, সংখ্যার তুলনার উপর ভিত্তি করে ফিল্টার করতে পারে, যেমন:

awk '$1 == 0' your_file

তবে সমস্ত শূন্যের চেয়ে বেশি সংখ্যক লাইন পেতে:

awk '$1 > 0' your_file

আমি রেগেক্সকে ভালবাসি, এটি দুর্দান্ত সরঞ্জাম। তবে এটি একমাত্র হাতিয়ার নয়। প্রবাদটি যেমন চলেছে, আপনার সমস্ত কিছু যদি হয় তবে grepসবকিছু নিয়মিত ভাষার মতো দেখাচ্ছে।


3
আমি আন্তরিকভাবে সম্মত হয়েছি যে এখানে awk আরও মার্জিত হতে পারে ... তবে এটি ব্যবহারকারীর প্রত্যাশার চেয়ে কিছুটা বেশি মিলবে (প্রতিটি সংখ্যার মান 0 তে মূল্যায়ন করবে)। অর্থাত, printf '0\n1\n-1\na\nb\n0\n0 also\n0.0\n-0.0\n0*0\n' | awk '($1 == 0)'ম্যাচ হবে: 0, 0.0এবং -0.0... এবং 0 also! শুধু "0" নয়। (যা কখনও কখনও যা প্রয়োজন, কখনও কখনও হয় না)। যদি ব্যবহারকারী কেবল "0" চান: awk '/^0$/' (বা grep '^0$')। এছাড়াও আপনার সম্পাদনা করা উচিত: !পরীক্ষার প্রত্যাখ্যান করার জন্য ব্যবহারকারীকে যুক্ত করা দরকার , সুতরাং এটি লুকিয়ে থাকে 0(এবং অন্যান্য শূন্যগুলি) এবং বাকী অংশটি প্রদর্শন করে। যেমন:awk '!( $0 == 0)'
অলিভিয়ার ডুলাক

1
@ অলিভিয়ার, বা স্ট্রিংয়ের মানটি পরীক্ষা করুন:$1 == "0"
গ্লেন জ্যাকম্যান

1
@ অলিভিয়ারডুলাক আমি (বা সমতুল্য ) >তুলনায় স্পষ্টভাবে ব্যবহার করেছি যে এটি কেবল সাম্য নয় বরং একটি স্বেচ্ছাসেবী সংখ্যার তুলনা। আপনার অন্যান্য মন্তব্য হিসাবে, এটি সম্পূর্ণ সত্য তবে তারপরে আমরা স্ট্রিং তুলনা অঞ্চল এবং কাজগুলি ব্যবহার করে বিদ্যমান সমাধানটিতে অবশ্যই ফিরে আসছি ( অবশ্যই এটিও কাজ করে)। !=! (… == …)grepawk
কনরাড রুডল্ফ

@ কনরাড রুডল্ফ ফর্সা পয়েন্ট :)
অলিভিয়ার ডুলাক

1
@glennjackman: দুর্দান্ত কৌশল। তবে ওপি বরং পরীক্ষা করবে$0=="0"
অলিভিয়ার ডুলাক

5

grepএর -wকিছুটা এমনভাবে সংশ্লেষিত হয় যে এটি শব্দটি এবং শব্দহীন উপাদানগুলিতে (অক্ষর, অঙ্ক বা আন্ডারস্কোর ব্যতীত অন্য কোনও ক্ষেত্রে) মূল স্ট্রিং বিভক্ত হয়। যেহেতু এটি ইতিমধ্যে একটি বৈধ শব্দের উপাদানটির মুখোমুখি 0হয়েছে 0.02তাতে লাইনটি সরাতে অস্বীকৃতি যুক্তি দিয়েছিল।

sedমেলে পুরো শব্দগুলি সরাতে এই প্রসঙ্গে ব্যবহার করা কিছুটা সহজ is

sed '/^0$/d' file

3

লাইন আপনি মুছে ফেলতে চান, তখন শুধুমাত্র ধারণ একটি 0 পরের লাইনে দ্বারা অনুসরণ আপনি নিম্নলিখিত কমান্ডের যারা লাইন নির্বাচন করতে পারেন:

grep -v "^0$"

এটি কেবলমাত্র ঘটনা ঘটার প্রিন্ট হবে 0যে একটি লাইন শেষে এবং একটি লাইন শুরুতে একই সময়ে। -vবিকল্প তাহলে আমাদের নির্বাচন inverts।


1
এই উত্তরটি আরকাদিউস দ্রাব্যাসিকের মতো প্রায় একই, তবে আপনি এটি ভুলে গেছেন -v, সুতরাং এটি কার্যকর হয় না।
স্পারহাক

তুমি ঠিক বলছো. তিনি তার উত্তর পোস্ট করার সময় আমি টাইপ করছিলাম তাই ইতিমধ্যে এটি দেওয়া হয়েছে তা আমি দেখতে পাইনি। আমি -vবিকল্পটি সেই অংশটি ভুলভাবে লিখেছি , ধন্যবাদ!
মার্জিক্যালএলএসডি

0
  • \ খ - শব্দের সীমানা

grep -v "\b0\b"

  • লাইনের শুরু, আপনার প্যাটার্ন এবং লাইনের শেষের সাথে মিল

grep -v "^0$"

  • বা হিসাবে @ স্পারহাক প্রস্তাবিত -vx লাইনরেজপ্প

-আমরা কাজ করে তবে আপনার ক্ষেত্রে ০.২ টি দুটি শব্দ কারণ বিন্দু অক্ষর একটি শব্দ বিভাজক।


grep -v "\b0\b"সত্যিই এখানে কাজ করে না। আপনি গ্রিপের কোন সংস্করণ ব্যবহার করেন?
আরকাদিউস দ্রবকিজিক

সাথে কাজ করে grep (BSD grep) 2.5.1-FreeBSDMacOS এবং grep (GNU grep) 2.16উবুন্টু উপর
Jakub Jindra

1
জিএনইউ রেজেক্স \<এবং \>শব্দ সীমানা হিসাবে ব্যবহার করে তবে এর একই প্রভাব থাকবে-w
গ্লেন জ্যাকম্যান

0

আপনার কাছে একটি পিসিআরই-সক্ষম আছে তা ধরে নিয়ে বৈচিত্রের জন্য আরেকটি উত্তর grep

grep -Pv "^0(?!\.)"

এটি বিন্দু দিয়ে শুরু হওয়া লাইনের সাথে মেলে এবং একটি বিন্দু অনুসরণ করে না head তারপরে মিলছে না এমন লাইনগুলি বাতিল করে। আপনি এখানে কর্মে দেখতে পাবেন0-v


1
এটি এর মতো লাইনগুলিও সরিয়ে ফেলবে 0123, যা ওপি যা চায় তা নয়
ইরুবার

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