जब कट कट नहीं करता है तो मुझे क्या उपयोग करना चाहिए?


19

मेरे पास citiesइस तरह की एक फाइल है:

[1598] San Diego, US (inactive)
[4517] St Louis, US (inactive)
[6346] Orlando, US (inactive)

मैं शहर के नाम काट देना चाहता हूं, ताकि मेरे पास:

San Diego
St Louis
Orlando

यह सबसे अच्छा मैं के साथ आ सकता है:

cut -d ',' -f1 cities | cut -d ']' -f2

लेकिन वह अभी भी मुझे नामों से पहले एक स्थान के साथ छोड़ देता है। क्या ऐसी कोई cutआज्ञा है जिसका उपयोग मैं कई पात्रों के परिसीमन को स्वीकार कर सकता हूं ताकि मैं काट सकूं ]?


1
trउन पात्रों को हटाने के लिए उपयोगी है जिन्हें आप नहीं चाहते हैं।
लॉरेंस

यदि आप लोगों के उत्तरों में कोड आज़माते हैं, तो आपको तीन अलग-अलग आउटपुट दिखाई देंगे। इससे पता चलता है कि आपका प्रश्न 100% स्पष्ट नहीं था। क्या "कट आउट" का मतलब निकालें या चयन करें? आप (inactive)स्थिति चाहते हैं या नहीं? कृपया नमूना आउटपुट प्रदान करें।
मिकेल

@ मिकेल - ध्यान में रखते हुए मैं cutचीजों को काटने के लिए उपयोग कर रहा हूं और आप मेरे द्वारा किए गए असफल उदाहरण के इरादे को देख सकते हैं, यह संदर्भ में बिल्कुल स्पष्ट होना चाहिए। मैं नमूना बाहर प्रदान करेगा, हालांकि इसे और अधिक स्पष्ट करने के लिए। :)
किट सुंडे

नहीं वास्तव में नहीं। मैंने आपके प्रश्न में एक वाक्य को "केवल शहर के नाम छापने" के लिए बदल दिया, क्योंकि यह "कट" शब्द का उपयोग था जो मेरे लिए अस्पष्ट था। क्या मेरा बदलाव सही है?
मिकेल

1
@ किट सुंडे: नमूना आउटपुट के साथ, यह निश्चित रूप से समझ में आता है। शीर्षक प्यारा है। "कट आउट" मुझे लगता है कि क्या होता है जब आप Ctrl + X दबाते हैं, यही कारण है कि मैंने बदलाव का सुझाव दिया है, लेकिन यह आपका सवाल है। डाउनवोटिंग मूर्खतापूर्ण होगा जब यह सिर्फ एक साधारण असहमति होगी।
मिकेल

जवाबों:


15

Awk (यह भी देखें कि Awk Info ) इस तरह के प्रश्न से सुंदर है। प्रयत्न:

awk -F'[],] *' '{print $2}' cities

यह एक क्षेत्र विभाजक -Fको परिभाषित करता है [],] *- जिसका अर्थ है एक समापन वर्ग कोष्ठक या अल्पविराम का एक घटना, जिसके बाद शून्य या किसी भी संख्या में रिक्त स्थान है। बेशक आप किसी भी आवश्यकता के अनुरूप इसे बदल सकते हैं। नियमित अभिव्यक्तियों पर पढ़ें।

एक बार जब लाइन विभाजित हो जाती है, तो आप वह कर सकते हैं जो आप विभाजन परिणाम के साथ चाहते हैं। यहां, मैंने केवल दूसरे क्षेत्र का प्रिंट आउट लेने का फैसला किया print $2। ध्यान दें कि आवक निर्देशों के आसपास एकल उद्धरणों का उपयोग करना महत्वपूर्ण है अन्यथा $ 2 शेल द्वारा प्रतिस्थापित किया जाता है।


2
]कोण कोष्ठक नहीं है। कोण कोष्ठक हैं <>[]"वर्गाकार कोष्ठक" हैं, या केवल "कोष्ठक" हैं।
cjm

मुझे लगता है कि आपको उस समापन कोष्ठक से बचने की आवश्यकता है, जब तक कि मुझे वास्तव में मेरे नियमित अभिव्यक्तियों पर पढ़ने की आवश्यकता न हो।
किट सुंडे

@ cjm - शायद वह जर्मन है: news.ycombinator.com/item?id=1181243 :)
किट

1
@ cjm, क्षमा करें, मेरा मतलब वर्ग कोष्ठक से है, थोड़ा बहुत तेज टाइप किया है। @ किट, मैं जर्मन नहीं हूं। आप आंतरिक समापन कोष्ठक से बचना नहीं चाहते (यह कोई उद्देश्य नहीं होगा), लेकिन यह सीमा में पहला चरित्र होना चाहिए।
asoundmove

12

आप cutअपनी पाइपलाइन में अंतिम को इसमें संशोधित कर सकते हैं :

cut -d ' ' -f2-

उपरोक्त का अर्थ है कि क्षेत्र विभाजक व्हाट्सएप है, और हम दूसरे से शुरू होने वाले सभी क्षेत्रों का चयन करना चाहते हैं। पूरा क्रम बन जाता है:

cut -d ',' -f1 cities | cut -d ' ' -f2-

12

अधिक जटिल पार्सिंग के लिए, आपको sed (1) का उपयोग करना चाहिए :

sed -e 's/\[[0-9]\+\] \([^,]\+\),.*/\1/' cities

या -rनियमित अभिव्यक्ति को सरल बनाने के लिए उपयोग करना, जैसा कि पेपोलुआन द्वारा सुझाया गया है :

sed -re 's/\[[0-9]+\] ([^,]+),.*/\1/' cities

2
+1। आप उन्नत रेगेक्स
चार्ट से

0

मैं आमतौर पर पर्ल का उपयोग करता हूं जब चीजें सीड और ग्रीप के लिए बहुत मुश्किल हो जाती हैं।

कई तरीके हैं जिनसे आप इसे पर्ल में लिख सकते हैं। उदाहरण के लिए, आप इसे तेज होना पसंद कर सकते हैं, या आप इसे इनपुट में थोड़ी अप्रत्याशित समस्याओं को संभालने के लिए पसंद कर सकते हैं (उदाहरण के लिए दो स्थान जहां एक की उम्मीद थी)।

एक स्पष्ट तरीका (माना जाता है कि आईडी संख्यात्मक है, शहर अल्फ़ाबेटिक है, स्थिति अल्फ़ाबेटिक है):

while (<>) {
    if (/^\[\d+\] (\w+(?: \w+)*), \w+ \(\w*\)$/) {
        my $city = $1;
        print "$city\n";
    }
}

या धीमी लेकिन अधिक अनुमेय (अधिक पीछे हटने पर):

while (<>) {
    if (/^.*\]\s+(.*),.*$/) {
        my $city = $1;
        print "$city\n";
    }
}

या तेज़ी से (ब्रैकेट बंद करने की पहली घटना पर क्षेत्र रुक जाता है):

while (<>) {
    if (/^\[[^]]*\] ([^,]*), \S+ \([^)]*\)$/) {
        my $city = $1;
        print "$city\n";
    }
}

स्क्रिप्ट के बजाय कमांड लाइन से, आप -nविकल्प का उपयोग कर सकते हैं , जो मूल रूप से while (<>) { BLOCK }लूप जोड़ता है :

perl -ne '/^\[[^]]*\] ([^,]*), \S+ \([^)]*\)$/ and print $1, "\n";' cities

या यदि आप कट के सदृश उपयोग करना चाहते हैं, तो आप -Fविकल्प का उपयोग कर सकते हैं , जो awk के -Fविकल्प के समान है , उदाहरण के लिए:

perl -a -n -F'/[],]\s+/' -e 'print $F[1], "\n"' cities

इस तरह स्पष्ट रूप से माना जाता है कि किसी भी क्षेत्र में कोई भी सीमांकक नहीं होगा।

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