2009-08-07 19 views
14

मेरे पास इसमें विभिन्न प्रविष्टियों के साथ एक टेक्स्ट फ़ाइल है। प्रत्येक प्रविष्टि लाइन के साथ समाप्त होती है जिसमें सभी तारांकन होते हैं।मैं अपनी नियमित अभिव्यक्ति के मिलान को चर के लिए कैसे आवंटित कर सकता हूं?

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

 
*********** 
Field1 
*********** 
Lorem ipsum 
Data to match 
*********** 
More data 
Still more data 
*********** 

यहाँ मेरी समाधान अब तक ऐसा दिखाई देता है:

यहाँ एक उदाहरण इनपुट फ़ाइल है

#!/bin/bash 
for error in `python example.py | sed -n '/.*/,/^\**$/p'` 
do 
    echo -e $error 
    echo -e "\n" 
done 

बहरहाल, यह सिर्फ $ त्रुटि के लिए मिलान पाठ में प्रत्येक शब्द प्रदान करती है, बल्कि एक पूरे ब्लॉक से।

उत्तर

23

मैं यहां मूल बैश समाधान नहीं देखकर आश्चर्यचकित हूं। हां, बैश नियमित अभिव्यक्ति है। आप ऑनलाइन यादृच्छिक दस्तावेज ऑनलाइन प्राप्त कर सकते हैं, खासकर यदि आप अपनी क्वेरी में "bash_rematch" शामिल करते हैं, या केवल मैन पेज देखें। यहां एक मूर्ख उदाहरण है, जिसे here से लिया गया है और एक नियमित अभिव्यक्ति के लिए, प्रत्येक मैच को मुद्रित करता है, और प्रत्येक कैप्चर किए गए मैचों को संशोधित करता है।

if [[ $str =~ $regex ]]; then 
    echo "$str matches" 
    echo "matching substring: ${BASH_REMATCH[0]}" 
    i=1 
    n=${#BASH_REMATCH[*]} 
    while [[ $i -lt $n ]] 
    do 
     echo " capture[$i]: ${BASH_REMATCH[$i]}" 
     let i++ 
    done 
else 
    echo "$str does not match" 
fi 

महत्वपूर्ण बिट है कि विस्तारित परीक्षण [[ ... ]] अपने रेगुलर एक्सप्रेशन से तुलना =~ भंडार ${BASH_REMATCH[0]} में पूरे मैच और ${BASH_REMATCH[i]} में कब्जा मैचों का उपयोग कर रहा है।

+1

वास्तव में, यह अच्छा होगा यदि वहाँ नियमित अभिव्यक्ति पार्टी की योजना बनाई एक निश्चित गाइड था, लेकिन जैसे @Jefromi कहा, यह सिर्फ अनियमितता का एक समूह है किया जाएगा। – g33kz0r

+0

@ नोहा: मैन पेज से: "ऑपरेटर के दाईं ओर की स्ट्रिंग को एक विस्तारित नियमित अभिव्यक्ति माना जाता है और तदनुसार मिलान किया जाता है (जैसा कि रेगेक्स (3) में है।" तो यह पॉज़िक्स विस्तारित रेगेक्स है, हाँ? ऐसा लगता है ... काफी । निश्चित – Cascabel

+0

सब कुछ ठीक है और अच्छा है, Jefromi है कि लेकिन यह diveintobashregex.org नहीं कर रहा है – g33kz0r

0

क्या आप चर

साथ क्या करना चाहते हैं पर निर्भर करता
awk ' 
f && /\*/{print "variable:"s;f=0} 
/\*/{ f=1 ;s="";next} 
f{ 
    s=s" "$0 
}' file 

उत्पादन:

# ./test.sh 
variable: Field1 
variable: Lorem ipsum Data to match 
variable: More data Still more data 

ऊपर सिर्फ उन्हें बाहर प्रिंट करता है। अगर आप चाहते हैं, बाद में उपयोग के लिए सरणी में दुकान ... जैसे सरणी [++ घ] = रों

1

आप बैश में यह करने के लिए चाहते हैं, आप निम्नलिखित की तरह कुछ कर सकता है। यह regexps (ताकि हम केवल तारक से मिलकर एक लाइन से मिलान कर सकते extglob खोल विकल्प, विस्तारित पैटर्न मिलान सक्षम बनाता है।)

#!/bin/bash 
shopt -s extglob 
entry="" 
while read line 
do 
    case $line in 
     +(\*)) 
      # do something with $entry here 
      entry="" 
      ;; 
     *) 
      entry="$entry$line 
" 
      ;; 
    esac 
done 
0

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

 
record start: 
this is a 2-line 
record 

record end 
record start: 

the 2nd record 
is 3 lines 
long 

record end 
record start: 

a 3rd * record 

record end 
+0

ध्यान दें कि स्क्रिप्ट लगभग निश्चित रूप से दिए गए आवश्यकता है/bin/श बैश किया जाना है। –

1

आदेश को दोहरे उद्धरण चिह्नों डालने का प्रयास करें:

#!/bin/bash 

foo() { 
    echo record start: 
    echo "[email protected]" 
    echo record end 
} 
export -f foo 

perl -e "$/='********'; while(<>){chomp;system(\"foo '\$_'\")}" << 'EOF' 
this is a 2-line 
record 
******** 
the 2nd record 
is 3 lines 
long 
******** 
a 3rd * record 
EOF 

यह निम्न उत्पादन देता है।

#!/bin/bash 
for error in "`python example.py | sed -n '/.*/,/^\**$/p'`" 
do 
    echo -e $error 
    echo -e "\n" 
done 
संबंधित मुद्दे