यदि पहली पंक्ति एक निश्चित पैटर्न से मेल खाती है तो केवल फ़ाइल सामग्री कैसे प्रिंट करें?


11

मैं एक स्क्रिप्ट लिख रहा हूं, मैं यह जांचना चाहता हूं कि क्या फाइल की पहली पंक्ति एक निश्चित पैटर्न से मेल खाती है और यदि ऐसा है तो फाइल का प्रिंट आउट लें। इसे कैसे प्राप्त किया जा सकता है?

मैं पैटर्न के लिए कैसे जांच करूं? वहाँ पैटर्न के लिए जाँच करने के लिए एक रास्ता है और आउटपुट कुछ करने पर आधारित है ..

EDIT: कृपया इस प्रश्न पर एक नज़र डालें: /programming/5536018/how-to-get-match-regex-pattern-use-awk-from-file

मैं ऐसा कुछ चाहता हूं, लेकिन उनमें से किसी ने भी मेरे लिए काम नहीं किया। मैं मूल रूप से यह जांचना चाहता हूं कि पहली पंक्ति एक रेगेक्स पैटर्न से मेल खाती है या नहीं और उसके आधार पर फाइल की पंक्तियों को प्रिंट करें।


1
क्या उत्पादन आप उम्मीद कर रहे हैं? आप किस पैटर्न की तलाश कर रहे हैं? अब तक तुमने क्या प्रयास किये हैं?
ताचोमी

@tachomi संपादित कृपया एक नज़र रखना
मैथ्यू

जवाबों:


17

आप ऐसा कर सकते हैं ed:

ed -s infile <<\IN 2>/dev/null
1s/PATTERN/&/
,p
q
IN

चाल यहाँ बदलने के लिए प्रयास करने के लिए है PATTERNपर 1stखुद के साथ लाइन। edअगर यह निर्दिष्ट पैटर्न नहीं मिल रहा है तो त्रुटि होगी ,p(पूरी फाइल प्रिंट करें) केवल तभी निष्पादित होगी जब 1s/PATTERN/&/सफल होगा।

या साथ sed:

sed -n '1{
/PATTERN/!q
}
p' infile

इस qकरता है, तो पहली पंक्ति नहीं (करता UITs !) मैच PATTERN, अन्यथा यह pसब लाइनों rints।
या, जैसा कि टोबी स्पाइट ने बताया है , GNU के साथ sed:

sed '1{/PATTERN/!Q}' infile

Qसमान है qलेकिन यह पैटर्न स्पेस को प्रिंट नहीं करता है।


आप GNU सेड के लिए, या इससे पहले (पोर्टेबल) के Qबजाय ध्वज और आदेश की आवश्यकता नहीं कर सकते हैं : या , क्रमशः। qdq-npsed '1{/PATTERN/!Q}' infilesed -e '1{' -e '/PATTERN/!{' -e 'd' -e 'q' -e '}' -e '}' infile
टोबी स्पाइट

dआज्ञा चक्र को पुनरारंभ करता है जो हमेशा मुझे पकड़ता है! : - |
टोबे स्पीट

जीएनयू sedके साथ पहली sedकमांड शिकायत करती है sed: -e expression #1, char 10: extra characters after command(क्योंकि p), लेकिन edअंतिम sedसुझाव ठीक काम करते हैं।
स्किप्पी ले ग्रैंड गौरू

NB: इस उत्तर द्वारा प्रदान किए गए समाधानों में अन्य उत्तरों की तुलना में योग्यता होती है, कि उन्हें एक पाइप पर लागू किया जा सकता है।
स्किप्पी ले ग्रैंड गौरू

1
@SkippyleGrandGourou - आपने अर्धविराम वाले आदेशों को अलग किए बिना इसे एक-लाइनर में बदलने की कोशिश की - यह करने का उचित तरीका हैsed -n '1{/PATTERN/!q};p'
don_crissti

15

POSIX उपकरण छाती के साथ:

{ head -n 1 | grep pattern && cat; } <file

1
{डबल} <मीठा।
माइकस

@mikeserv: मैं नए व्यक्ति को भ्रमित होने से रोकने के लिए इसका उपयोग करने का इरादा रखता हूं, लेकिन स्टीफन द्वारा संपादित स्पष्ट है।
cuonglm

8
 awk '/pattern/{print FILENAME}; {nextfile}' ./*.txt

txtवर्तमान निर्देशिका में गैर-छिपी हुई फ़ाइलों का नाम प्रिंट करेगा जिनकी पहली पंक्ति उन समर्थनों केpattern साथ विस्तारित नियमित अभिव्यक्ति से मेल खाती है ।awknextfile

यदि फ़ाइल नाम प्रिंट करने के बजाय, आप पूरी फ़ाइल सामग्री प्रिंट करना चाहते हैं, तो आप कर सकते हैं:

 awk 'FNR == 1 && ! /pattern/ {nextfile}; {print}' ./*.txt

यह कुशल है कि यह केवल एक कमांड चलाता है, लेकिन awkकिसी फ़ाइल की सामग्री को डंप करने के लिए सबसे कुशल कमांड नहीं है, बड़ी फ़ाइलों के साथ, आप संभवतः कुछ ऐसा करके बेहतर प्रदर्शन प्राप्त कर सकते हैं:

 awk '/pattern/{printf "%s\0", FILENAME}; {nextfile}' ./*.txt |
   xargs -r0 cat

यही है, केवल उन awkफ़ाइलों की सूची को प्रिंट करने के लिए उपयोग करें जो (0-सीमांकित) से मेल खाते हैं और catउनकी सामग्री को डंप करने के लिए भरोसा करते हैं ।


6

यदि आप एक शेल स्क्रिप्ट लिख रहे हैं, तो आप ऐसा कुछ कर सकते हैं

for file in ./*; do head -n 1 "$file" | grep -q 'PATTERN' && cat "$file"; done

या, पर्ल में:

perl -Tlne '$f = /PATTERN/ if $. == 1; print if $f; $. = 0 if eof' ./*

@ स्टीफन चेज़लस: शायद close ARGVअसाइन करने से ज्यादा मुहावरा है $.
cuonglm

@terdon योरस कोड गोल्फ की तरह दिखता है, सभी एक पंक्ति में, चर नामों के आसपास कोई ब्रैकेट नहीं है और स्वच्छ संरचना को प्रोत्साहित नहीं कर रहा है। और आपके पास एक लापता डॉलर का चिह्न था जब मैंने पोस्ट किया था, तो बस बैश सिखाने का तरीका नहीं था। मुझे लगता है कि उन कारकों में से एक पृष्ठभूमि है जो आपको भी लगती है, इसलिए आपको माफ कर दिया जाएगा! ;)

@guest हाय और साइट पर आपका स्वागत है! मैंने आपके उत्तर को एक टिप्पणी में बदल दिया क्योंकि उत्तर केवल तभी पोस्ट किए जाने चाहिए जब वे वास्तविक प्रश्न का उत्तर दे रहे हों। यह क्लासिक अर्थों में एक मंच नहीं है और हम केवल यहां शुद्ध क्यू एंड ए चाहते हैं। आप मदद केंद्र पर एक नज़र डालना चाहते हैं या साइट को बेहतर समझने के लिए दौरे ले सकते हैं । उस ने कहा, मेरी पृष्ठभूमि वास्तव में जीव विज्ञान में है इसलिए हां, मेरा कोड साफ से बहुत दूर है :) हालांकि, मैं यह नहीं देखता कि कैसे कोष्ठक यहां मदद करेंगे, उद्धरण पहले से ही चर की रक्षा करते हैं। इससे क्या टूटेगा कि कोष्ठक से रक्षा होगी?
terdon

@guest आह, क्षमा करें, भूल गए आप टिप्पणी नहीं कर सकते। बेझिझक आएं और चैट में समझाएं , मुझे यकीन है कि मैं कुछ सीख सकता हूं।
terdon

5

ऑल्‍डस्कूल, बस अपनी वाक्‍य का अनुवाद मानक कमांडों में करें:

for file in *; do
    if head -n 1 "${file}" | grep -q 'PATTERN'; then
        cat "${file}"
    fi
done

बाश सीखने के लिए जो एक अच्छी शुरुआत है। अगर आपको सिर्फ एक त्वरित समाधान की आवश्यकता है, तो sed-, awk- या perl-answer को आज़माएं। दोनों अच्छे हैं, लेकिन वे सीखने के लिए (और शायद चाहते हैं) अपनी भाषाएं हैं।

यह एक बहुत ही सरल उदाहरण है, इसलिए यदि आप और अधिक सीखना चाहते हैं, तो आप रूबी, php, js (जैसे नोड्ज में) या किसी अन्य भाषा में भी कोशिश कर सकते हैं जो फ़ाइल तक पहुँचने की अनुमति देती है। यहां तक ​​कि सी / सी ++ या जावा को एक छोटे से काम के साथ प्रबंधित करना आसान होना चाहिए।


1
यह मूल रूप से खान के समान है सिवाय इसके कि आप if/elseइसके बजाय उपयोग करते हैं [ ] &&
terdon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.