एक विशिष्ट कॉलम में निश्चित मान रखने वाली पंक्तियों को कैसे पकड़ें?


9

मेरे पास निम्नलिखित के रूप में एक फाइल है

  200.000    1.353    0.086
  200.250    1.417    0.000
  200.500    1.359    0.091
  200.750    1.423    0.000
  201.000    1.365    0.093
  201.250    1.427    0.000
  201.500    1.373    0.093
  201.750    1.432    0.000
  202.000    1.383    0.091
  202.250    1.435    0.000
  202.500    1.392    0.087
  202.750    1.436    0.000
  203.000    1.402    0.081
  203.250    1.437    0.001
  203.500    1.412    0.073
  204.000    1.423    0.065
  204.500    1.432    0.055
  205.000    1.441    0.045  

मैं केवल उन पंक्तियों को अपनाना चाहूंगा जिनके पहले कॉलम में दशमलव .000 और .500 है, इसलिए केवल आउटपुट ही ऐसा होगा।

  200.000    1.353    0.086
  200.500    1.359    0.091
  201.000    1.365    0.093
  201.500    1.373    0.093
  202.000    1.383    0.091
  202.500    1.392    0.087
  203.000    1.402    0.081
  203.500    1.412    0.073
  204.000    1.423    0.065
  204.500    1.432    0.055
  205.000    1.441    0.045  

2
यह काफी आसान लगता है। अब तक तुमने क्या प्रयास किये हैं? आपके कोड में क्या समस्याएं थीं?
जॉन 1024

शायद यह आपके लिए आसान हो, लेकिन मैंने '.000' के साथ कोशिश की grep '.005' लेकिन यह अन्य पंक्तियों में समान मान रखने वाली पंक्तियों को भी
छाँटता है

3
बहुत अच्छा। यहां के लोग बहुत अधिक सहानुभूति रखते हैं यदि आप समस्या को स्वयं हल करने का ईमानदार प्रयास दिखाते हैं। आपकी टिप्पणी में कोड दिखाता है कि। भविष्य में, यदि आप अपने प्रश्न में इस तरह के प्रयास शामिल करते हैं, तो आपको संभवतः बेहतर प्रतिक्रियाएं प्राप्त होंगी।
जॉन 1024

जवाबों:


14

आप grep का उपयोग नहीं करते हैं। का उपयोग करें awk

"your data" | awk '$1 ~ /\.[05]00/'

बहुत अच्छा। जैसा कि लिखा गया है, कोड दशमलव के बाद तीन अंकों के होने पर निर्भर करता है। यह उपयोग करने के लिए अधिक मजबूत होगा awk '$1 ~ /\.[05]0*$/'
जॉन 1024

1
@ जॉन 1024, जैसा कि लिखा गया कोड वास्तव में दशमलव के बाद कम से कम तीन अंक होने पर निर्भर करता है । awk '$1 ~ /\.[05]00$/'जब तक मेरे पास यह सोचने का कारण नहीं था कि इनपुट में वैरिएबल दशमलव स्थानों की अपेक्षा है, मैं अपने आप को (तीन अंकों की आवश्यकता) की ओर झुकूंगा ।
वाइल्डकार्ड

2
@Wildcard यदि तीन से अधिक हैं, तो कोड विफल हो सकता है। उदाहरण के लिए echo 0.5001 | awk '$1 ~ /\.[05]00/':। यह केवल मज़बूती से काम करता है अगर वास्तव में तीन हैं।
23:10 पर जॉन 1024

4
awk '$1 ~ /\.[50]00/ { print $0 }' myFile.txt

पहले कॉलम $1का मिलान उन /\.500|\.000/बिंदुओं से किया जाएगा जो शाब्दिक बिंदु होने से बच जाते हैं, किसी भी वर्ण को फिर ~से विभाजित नहीं करते हैं जो कि आंशिक मैच है, और पूरी लाइन प्रिंट करें$0


2
शामिल करने का कोई कारण नहीं { print $0 }; वह अवाक की डिफ़ॉल्ट कार्रवाई है।
वाइल्डकार्ड

4

मैं केवल उन पंक्तियों को अपनाना चाहूंगा, जिनके पहले कॉलम में दशमलव .000 और .500 है

मेरा पहला विचार

grep '^ *[0-9][0-9][0-9]\.[50]00' filename

WSL का उपयोग करके त्वरित परीक्षण

$ head testdata
              200.000    1.353    0.086
              200.250    1.417    0.000
              200.500    1.359    0.091
              200.750    1.423    0.000
              201.000    1.365    0.093
              201.250    1.427    0.000
              201.500    1.373    0.093
              201.750    1.432    0.000
              202.000    1.383    0.091
              202.250    1.435    0.000
$ grep '^ *[0-9][0-9][0-9]\.[50]00' testdata
              200.000    1.353    0.086
              200.500    1.359    0.091
              201.000    1.365    0.093
              201.500    1.373    0.093
              202.000    1.383    0.091
              202.500    1.392    0.087
              203.000    1.402    0.081
              203.500    1.412    0.073
              204.000    1.423    0.065
              204.500    1.432    0.055
              205.000    1.441    0.045

इसे व्यक्त करने के लिए और अधिक संक्षिप्त तरीके हैं।

$ grep -E '^ *[0-9]{3}\.[50]00' testdata
              200.000    1.353    0.086
              200.500    1.359    0.091
              201.000    1.365    0.093
              201.500    1.373    0.093
              202.000    1.383    0.091
              202.500    1.392    0.087
              203.000    1.402    0.081
              203.500    1.412    0.073
              204.000    1.423    0.065
              204.500    1.432    0.055
              205.000    1.441    0.045

यदि पहला कॉलम 3-अंकीय पूर्णांक भाग के अलावा हो सकता है

grep -E '^ *[0-9]+\.[05]00' testdata

कुछ परिस्थितियों में आपको इसके [:digit:]स्थान पर उपयोग करने की आवश्यकता हो सकती है [0-9]

और इसी तरह।

man grep आपका दोस्त है।


यह उपयोग grepमेरा की तुलना में उपयोग करना आसान है। मैं एक जवाब पोस्ट नहीं किया है मुझे पहले यह देखना चाहिए था। अच्छी नौकरी!
Yokai

2

आपके उपयोग के मामले के आधार पर, आप वास्तविक संख्यात्मक कार्यों का भी उपयोग कर सकते हैं:

$ awk '{a = $1 % 1} a == 0 || a == 0.5' /tmp/foo
  200.000    1.353    0.086
  200.500    1.359    0.091
  201.000    1.365    0.093
  201.500    1.373    0.093
  202.000    1.383    0.091
  202.500    1.392    0.087
  203.000    1.402    0.081
  203.500    1.412    0.073
  204.000    1.423    0.065
  204.500    1.432    0.055
  205.000    1.441    0.045

BSD awk (OSX El Capitan, 20070501) और GNU awk 4.1.4 के साथ परीक्षण किया गया।


1
चेतावनी: फ्लोटिंग-पॉइंट (जो awk उपयोग करता है) की सटीक समानता का परीक्षण अक्सर तब तक 'गलत' परिणाम देता है जब तक कि मानों में कोई अंश नहीं होता (और परिमाण में बहुत बड़ा नहीं होता), या भिन्नात्मक भाग 'बाइनरी' (ठीक आधा), क्वार्टर, आदि) जो इस क्यू में डेटा के लिए सच है, लेकिन कई अन्य जो कि असमान के समान दिखाई देते हैं।
dave_thompson_085

1
@ dave_thompson_085 वास्तव में, लेकिन gawk के साथ आप मनमाने ढंग से सटीक अंकगणित का उपयोग कर सकते हैं , बेशक मैं यहाँ उनका उपयोग नहीं कर रहा हूँ।
मूरू


2

के साथ awk:

$>awk '$1%.5==0' data.tsv 
200.000 1.353   0.086
200.500 1.359   0.091
201.000 1.365   0.093
201.500 1.373   0.093
202.000 1.383   0.091
202.500 1.392   0.087
203.000 1.402   0.081
203.500 1.412   0.073
204.000 1.423   0.065
204.500 1.432   0.055
205.000 1.441   0.045

के साथ mlr:

$>mlr --ifs tab --onidx filter '$1%.5==0' data.tsv 
200.000 1.353 0.086
200.500 1.359 0.091
201.000 1.365 0.093
201.500 1.373 0.093
202.000 1.383 0.091
202.500 1.392 0.087
203.000 1.402 0.081
203.500 1.412 0.073
204.000 1.423 0.065
204.500 1.432 0.055
205.000 1.441 0.045

2

ठीक है, मेरे योगदान में थोड़ा देर से जोड़ना, लेकिन मुझे लगता है कि यह इसके लायक है।

ओपी के अनुसार मिलने की आवश्यकता, पहला कॉलम है जिसमें केवल .000या .500केवल दशमलव मान है । सीमा या लंबाई के आधार पर अग्रणी मूल्य के अनुसार कोई वजीफा नहीं है। मजबूती के लिए इसे किसी भी चीज के लिए विवश नहीं माना जाना चाहिए, सिवाय इसके कि पहले कॉलम से पहले कोई गैर-रिक्त अक्षर नहीं हैं (या यह अब पहला कॉलम नहीं है) और पहले कॉलम की सामग्री में दशमलव बिंदु होगा. , इसमें कहीं

ओपी उपयोग करना चाहता है grep, जो एक मैच पाए जाने पर पूरी लाइन को प्रिंट करेगा, इसलिए केवल एक चीज जो पैटर्न बना रही है वह सभी से मेल खाती है और केवल उसी चीज की आवश्यकता होती है।

सादगी ही, और `grep के रूप में sedया उपयोग करने के लिए कोई कारण awkस्रोत फ़ाइल या पाइप के रूप में संभाल कर सकते हैं।

grepएक फ़ाइल का उपयोग करने के लिएgrep '^[^.]*\.[05]0\{2\}\s' the_file.txt

करने के लिए grepएक पाइप, उपयोग सेmy_command | grep '^[^.]*\.[05]0\{2\}\s'

पैटर्न है: ^लाइन की शुरुआत में शुरू; [^.], किसी भी गैर-दशमलव वर्ण से मेल खाता है; *, जितनी बार संभव हो (सहित कोई नहीं); \., एक दशमलव बिंदु से मेल खाता है; [05], मैच या तो एक पांच या एक शून्य; 0\{2\}, 2 और शून्य का मिलान करें (खुले और बंद ब्रेस से पहले बैकस्लैश शेल को ब्रेस एक्सपोज़र करने की कोशिश से रोकते हैं); \s, एक व्हाट्सएप चरित्र से मेल खाता है (स्तंभ के अंत का अर्थ है - एक अलग उपयोग के मामले में उपयोग करने के लिए, स्तंभ विभाजक के साथ बदलें, आमतौर पर एक कॉमन, एक अर्ध-उपनिवेश या एक टैब \t)।

ध्यान दें कि यह ठीक वही होगा जो ओपी ने पूछा था। यह होगा नहीं मेल खाते हैं .5000या .0000फिर भी संख्यानुसार बराबर है, क्योंकि एक पांच या एक शून्य के लिए पैटर्न दिखता है, वास्तव में, जिसके बाद 2 अधिक शून्य खाली स्थान के द्वारा पीछा किया। यदि यह महत्वपूर्ण है, तो अन्य सभी उत्तर, अब तक, इसमें विफल हैं कि वे परीक्षण अंक के बाद, किसी भी संख्या में शून्य, 1 से अधिक से मेल खाएंगे। और FloHimself से जवाब देने के लिए छोड़कर, वे से मेल खाएगा कुछ भी दूसरे स्तंभ है कि में शुरू होता है .000 या .500, सहित .0003और .500T, और FloHimself के बाद एक कुछ भी मिलान कर देंगे कि गणितीय के बराबर है .0और.5कोई फर्क नहीं पड़ता कि कितने शून्य हैं। पिछले एक, जबकि मिलान नहीं है जो ओपी ने कहा था कि ओपी को वैसे भी क्या चाहिए मैच होने की संभावना है।

अंत में, यदि awkओपी ने कहा कि भले ही बिजली, और गति, वांछित है grep, तो कमांड होगी:

एक फ़ाइल के साथ awk '$1 ~ /[^.]\.[05]0{2}$/' the_file.txt

एक पाइप के साथ my_command | awk '$1 ~ /[^.]\.[05]0{2}$/'


1

यदि आप grep का उपयोग करने पर जोर देते हैं, तो यह आपके लिए काम कर सकता है। मैंने आपके द्वारा प्रदान किए गए पहले आउटपुट को "file.txt" नामक एक फ़ाइल में सहेजा है और फिर निम्न कमांड का उपयोग किया है:

grep -e '2[^ ]*.000' file.txt & grep -e '2[^ ]*.500' file.txt

जो इसका आउटपुट देता है:

200.000    1.353    0.086
200.500    1.359    0.091
201.500    1.373    0.093
201.000    1.365    0.093
202.500    1.392    0.087
202.000    1.383    0.091
203.500    1.412    0.073
203.000    1.402    0.081
204.500    1.432    0.055
204.000    1.423    0.065
205.000    1.441    0.045

अगर यह पहले से ही एक फ़ाइल में है, तो आपको आउटपुट को टेक्स्ट फ़ाइल में सहेजना नहीं पड़ेगा। लेकिन अगर यह किसी फाइल में सेव नहीं किया जा रहा है, तो आप मेरे द्वारा दिए गए grep कमांड में डेटा को पाइप भी कर सकते हैं और इसे कम से कम तब तक काम करना चाहिए जब तक 2कि पहला कॉलम पहले कॉलम में नहीं रह जाता है 2। उस बिंदु पर आपको सही तरीके से प्रिंट करने के लिए उपयुक्त वर्ण के साथ grep कमांड को अपडेट करना होगा।

इस दोहरी grepकमांड के साथ क्या हो रहा है कि पहले ऑपरेटर के grepसाथ पृष्ठभूमि में भेजा जा रहा है &। जैसा कि इसे पृष्ठभूमि में भेजा गया है, अगला grepकमांड आपको एक समान आउटपुट देने के तुरंत बाद निष्पादित करता है। उस कार्य के लिए जिसे आपको और अधिक आसानी से पूरा करने की आवश्यकता है, आपको उस उदाहरण का अनुसरण करना चाहिए जो दूसरों ने दिया है और उपयोग awkया यहां तक ​​कि sed

(संपादित करें)

यह किसी भी तरह से आपकी आवश्यकताओं के लिए grep का सबसे अच्छा या सबसे प्रभावी उपयोग नहीं है, लेकिन यह आपके लिए पर्याप्त होना चाहिए कि आप थोड़ा सा खेल सकें और grep के लिए बेहतर अनुभव प्राप्त कर सकें।


पहली प्रक्रिया बैकग्राउंड में चलती है, लेकिन डीमॉनेटाइज़्ड नहीं होती है, जिसमें बैकग्राउंड में रनिंग शामिल होती है, लेकिन काफी अधिक। और इनपुट के रूप में उसी क्रम में आउटपुट का उत्पादन करने की संभावना नहीं है; यहां तक ​​कि आपके छोटे उदाहरण में भी यह तीसरी पंक्ति में पहले से ही गलत है।
dave_thompson_085

वह यह उल्लेख नहीं करता है कि आउटपुट को एक विशिष्ट क्रम में होना चाहिए। केवल इसे करने के लिए विशिष्ट होने की जरूरत है कि .500और .000पहले कॉलम के। यदि इसकी आवश्यकता किसी विशिष्ट क्रम में हो, जैसे कि कम से कम से सबसे बड़ी, तो यह आसानी से किया जा सकता है। हालाँकि, मुद्रित किए जा रहे पहले कॉलम के पहले 3 अंक कम से कम सबसे बड़े क्रम में हैं। यही कारण है कि का परिणाम है 2[^ ]*.000और 2[^ ]*.500। ओपी ने जो पूछा, उसके लिए काफी उपयुक्त है।
योके

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