मैच से पहले और बाद में ग्रीप वर्ण?


144

इसका उपयोग करना:

grep -A1 -B1 "test_pattern" file

फ़ाइल में मिलान पैटर्न से पहले और बाद में एक लाइन का उत्पादन करेगा। क्या कोई रेखा नहीं बल्कि वर्णों की एक निर्दिष्ट संख्या प्रदर्शित करने का एक तरीका है?

मेरी फाइल की लाइनें बहुत बड़ी हैं इसलिए मुझे पूरी लाइन को प्रिंट करने में कोई दिलचस्पी नहीं है, बल्कि केवल संदर्भ में मैच का निरीक्षण करें। इस संबंध में कोई सुझाव कि इसे कैसे किया जा सकता है?


1
का डुप्लीकेट unix.stackexchange.com/q/163726 के पास की नकल stackoverflow.com/q/2034799
sondra.kinsey

जवाबों:


184

3 अक्षर पहले और 4 अक्षर बाद

$> echo "some123_string_and_another" | grep -o -P '.{0,3}string.{0,4}'
23_string_and

5
डेटा की छोटी मात्रा के लिए एक अच्छा जवाब है, लेकिन जब आप मिलान कर रहे होते हैं तो यह धीमी गति से शुरू होता है> 100 अक्षर - जैसे मेरी विशाल xml फ़ाइल में, मैं {1,200} पहले और बाद में चाहता हूं, और यह उपयोग करने के लिए बहुत धीमा है।
बेनुबर्ड

3
@Amit_g द्वारा awk संस्करण बहुत तेज है।
ssobczak

6
Mac OSX पर उपलब्ध नहीं है, इसलिए वास्तव में यह व्यापक रूप से उपलब्ध समाधान नहीं है। -E संस्करण (नीचे सूचीबद्ध) एक बेहतर समाधान है। -पी क्या है? आगे पढ़ें ... -P, --perl-regexp एक नियमित अभिव्यक्ति के रूप में पैटर्न की व्याख्या करें (PCRE, नीचे देखें)। यह अत्यधिक प्रायोगिक है और grep -P अनिमित सुविधाओं की चेतावनी दे सकता है।
Xofo

2
OSX पर: के माध्यम से स्थापित करें brew install homebrew/dupes/grepऔर इसे चलाएं ggrep
kenorb

1
जैसा कि @Benubird द्वारा निहित है, यह मैच-वार लक्ष्य के लिए वांछित विस्तृत परिवेश के साथ विशाल फ़ाइलों के लिए उपयोग करने के लिए निष्पादन-वार असंभव होगा।
मैटनस्टर

113
grep -E -o ".{0,5}test_pattern.{0,5}" test.txt 

यह आपके पैटर्न से पहले और बाद में 5 अक्षरों तक मेल खाएगा। -O स्विच केवल मैच दिखाने के लिए grep बताता है और एक विस्तारित नियमित अभिव्यक्ति का उपयोग करने के लिए -E। अपनी अभिव्यक्ति के चारों ओर उद्धरण डालना सुनिश्चित करें, अन्यथा इसे शेल द्वारा व्याख्या किया जा सकता है।


1
अच्छा जवाब, दिलचस्प है कि यह 2 ^ 8-1 की लंबाई में {} में छाया हुआ है, इसलिए {0,255}काम करता {0,256}हैgrep: invalid repetition count(s)
CodeMonkey

ऐसा लगता है कि मैं बहुत कम प्रदर्शन कर रहा हूं क्योंकि मैं मिलान वर्णों की संख्या बढ़ाता हूं (5 -> 25 -> 50), किसी भी विचार क्यों?
एडम ह्यूजेस

37

आप उपयोग कर सकते हैं

awk '/test_pattern/ {
    match($0, /test_pattern/); print substr($0, RSTART - 10, RLENGTH + 20);
}' file

2
अच्छी तरह से कुछ बड़ी फ़ाइलों के साथ भी काम करता है
टूको

4
आप प्रति पंक्ति में कई मिलान खोजने के लिए इसका उपयोग कैसे कर सकते हैं?
koox00

1
घुंघराले-जोड़े में पहले नंबर का क्या महत्व है? "Grep -E -o" में 0s की तरह। {0,5} test_pattern। {0,5} "test.tpat"?
ल्यू रॉकवेल फैन

यह वास्तव में तेज़ है लेकिन @ ekse के उत्तर जितना सटीक नहीं है।
अब्दुल्लाह

24

यानी तुम्हें ये पसंद है:

grep -o '.\{0,20\}test_pattern.\{0,20\}' file

?

इसके दोनों ओर बीस अक्षर तक प्रिंट होगा test_pattern\{0,20\}अंकन की तरह है *, लेकिन निर्दिष्ट के बजाय शून्य बीस पुनरावृत्ति करने के लिए शून्य या more.The -oकेवल मैच ही है, बल्कि पूरी रेखा से दिखाने के लिए कहते हैं।


यह आज्ञा मेरे लिए काम नहीं कर रही है:grep: Invalid content of \{\}
अलेक्जेंडर प्रवीण

0

के साथ gawk, आप मैच फ़ंक्शन का उपयोग कर सकते हैं:

    x="hey there how are you"
    echo "$x" |awk --re-interval '{match($0,/(.{4})how(.{4})/,a);print a[1],a[2]}'
    ere   are

यदि आप perlअधिक लचीले समाधान के साथ ठीक हैं , तो निम्न पैटर्न के पहले तीन वर्णों को प्रिंट करेगा और उसके बाद पैटर्न के बाद 5 वर्ण।

echo hey there how are you |perl -lne 'print "$1$2$3" if /(.{3})(there)(.{5})/'
ey there how

यह सिर्फ वर्णों के बजाय शब्दों पर भी लागू किया जा सकता है। वास्तविक मिलान स्ट्रिंग से पहले एक शब्द प्रिंट होगा।

echo hey there how are you |perl -lne 'print $1 if /(\w+) there/'
hey

पैटर्न के बाद एक शब्द प्रिंट होगा:

echo hey there how are you |perl -lne 'print $2 if /(\w+) there (\w+)/'
how

निम्नलिखित पैटर्न के पहले एक शब्द, उसके बाद वास्तविक शब्द और पैटर्न के बाद एक शब्द प्रिंट होगा:

echo hey there how are you |perl -lne 'print "$1$2$3" if /(\w+)( there )(\w+)/'
hey there how

0

हाइलाइट के लिए + grep खोजने के लिए आप regexp grep का उपयोग कर सकते हैं

echo "some123_string_and_another" | grep -o -P '.{0,3}string.{0,4}' | grep string

23_string_and

यहां छवि विवरण दर्ज करें


0

मैं आसानी से इन गुप्त आदेश संशोधक को आसानी से याद नहीं करूँगा इसलिए मैंने शीर्ष उत्तर लिया और इसे अपनी ~/.bashrcफ़ाइल में एक फ़ंक्शन में बदल दिया :


cgrep() {
    # For files that are arrays 10's of thousands of characters print.
    # Use cpgrep to print 30 characters before and after search patttern.
    if [ $# -eq 2 ] ; then
        # Format was 'cgrep "search string" /path/to/filename'
        grep -o -P ".{0,30}$1.{0,30}" "$2"
    else
        # Format was 'cat /path/to/filename | cgrep "search string"
        grep -o -P ".{0,30}$1.{0,30}"
    fi
} # cgrep()

यहाँ यह कार्रवाई में कैसा दिखता है:

$ ll /tmp/rick/scp.Mf7UdS/Mf7UdS.Source

-rw-r--r-- 1 rick rick 25780 Jul  3 19:05 /tmp/rick/scp.Mf7UdS/Mf7UdS.Source

$ cat /tmp/rick/scp.Mf7UdS/Mf7UdS.Source | cgrep "Link to iconic"

1:43:30.3540244000 /mnt/e/bin/Link to iconic S -rwxrwxrwx 777 rick 1000 ri

$ cgrep "Link to iconic" /tmp/rick/scp.Mf7UdS/Mf7UdS.Source

1:43:30.3540244000 /mnt/e/bin/Link to iconic S -rwxrwxrwx 777 rick 1000 ri

प्रश्न में फ़ाइल एक निरंतर 25K लाइन है और यह नियमित रूप से उपयोग करने के लिए आप क्या देख रहे हैं, यह खोजने के लिए निराशाजनक है grep

उन दो अलग-अलग तरीकों पर ध्यान दें, जिन्हें आप cgrepसमानताएं grepविधि कह सकते हैं ।

फ़ंक्शन बनाने का एक "निफ्टियर" तरीका है जहां "$ 2" केवल तभी पास होता है जब सेट किया जाता है जो कोड की 4 लाइनों को बचाएगा। हालांकि मेरे पास यह काम नहीं है। कुछ इस तरह ${parm2} $parm2। अगर मुझे लगता है कि मैं फ़ंक्शन और इस उत्तर को संशोधित करूँगा।

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