bash - science - there's a specific term for the patterns that grep lets you use




التقاط المجموعات من Grep RegEx (5)

أنا أدرك أن الإجابة كانت مقبولة بالفعل لهذا ، ولكن من "زاوية pcregrep تماما * نيكس" يبدو أن الأداة المناسبة لهذه الوظيفة هي pcregrep ، والتي لا يبدو أنها قد ذكرت حتى الآن. حاول تغيير الخطوط:

    echo $f | grep -oEi '[0-9]+_([a-z]+)_[0-9a-z]*'
    name=$?

الى الآتى \ الى القادم \ الى الم:

    name=$(echo $f | pcregrep -o1 -Ei '[0-9]+_([a-z]+)_[0-9a-z]*')

للحصول على محتويات مجموعة الالتقاط 1 فقط.

تستخدم أداة pcregrep كل نفس البنية التي استخدمتها بالفعل مع grep ، ولكنها تنفذ الوظيفة التي تحتاجها.

تعمل المعلمة -o تمامًا مثل إصدار grep إذا كانت عارية ، ولكنها تقبل أيضًا معلمة رقمية في pcregrep ، والتي تشير إلى مجموعة الالتقاط التي تريد إظهارها.

مع هذا الحل ، هناك حد أدنى من التغيير المطلوب في البرنامج النصي. يمكنك ببساطة استبدال إحدى الأدوات المعيارية بآخر وتغيير المعلمات.

ملاحظة مثيرة للاهتمام: يمكنك استخدام العديد من الوسيطات لإرجاع مجموعات التقاط متعددة بالترتيب الذي تظهر به على السطر.

لقد حصلت على هذا البرنامج النصي الصغير في sh (Mac OSX 10.6) للبحث في مجموعة من الملفات. توقفت Google عن تقديم المساعدة في هذه المرحلة:

files="*.jpg"
for f in $files
    do
        echo $f | grep -oEi '[0-9]+_([a-z]+)_[0-9a-z]*'
        name=$?
        echo $name
    done

حتى الآن (من الواضح أنه بالنسبة إلى معلمي shell) ، فإن $name يحمل فقط 0 أو 1 أو 2 ، وهذا يتوقف على ما إذا وجد grep أن اسم الملف متطابق مع المادة المقدمة. ما أريده هو تصوير ما يوجد داخل الأرفف ([az]+) وتخزينه لمتغير .

أود استخدام grep فقط ، إذا أمكن ذلك . إن لم يكن ، من فضلك لا بيثون أو بيرل ، وما إلى ذلك أو ما شابه ذلك - أنا جديدة على قذيفة ، وأود أن يهاجم هذا من زاوية نيكس * نيكس.

أيضا ، كبوون رائع جدا ، أنا فضولي إلى كيف يمكنني سلسلته سلسلة في شل؟ هل كانت المجموعة التي تم التقاطها هي السلسلة "somename" المخزنة في $ name ، وأردت إضافة السلسلة ".jpg" إلى نهايتها ، هل يمكنني أن أضع cat $name '.jpg' ؟

يرجى توضيح ما يحدث ، إذا كان لديك الوقت.


إذا كان لديك bash ، يمكنك استخدام globe ممتدة

shopt -s extglob
shopt -s nullglob
shopt -s nocaseglob
for file in +([0-9])_+([a-z])_+([a-z0-9]).jpg
do
   IFS="_"
   set -- $file
   echo "This is your captured output : $2"
done

أو

ls +([0-9])_+([a-z])_+([a-z0-9]).jpg | while read file
do
   IFS="_"
   set -- $file
   echo "This is your captured output : $2"
done

اقتراح لك - يمكنك استخدام توسيع المعلمة لإزالة جزء الاسم من السطر السفلي الأخير فصاعدًا ، وبالمثل في البداية:

f=001_abc_0za.jpg
work=${f%_*}
name=${work#*_}

ثم سيكون name قيمة abc .

راجع مستندات مطور Apple ، ابحث عن "توسيع المعلمة".


غير ممكن في grep فقط أعتقد

لسد:

name=`echo $f | sed -E 's/([0-9]+_([a-z]+)_[0-9a-z]*)|.*/\2/'`

سآخذ طعنة على المكافأة على الرغم من:

echo "$name.jpg"

هذا هو الحل الذي يستخدم gawk. إنه شيء أجد أنني بحاجة إلى استخدامه في كثير من الأحيان لذلك أنا خلقت وظيفة لذلك

function regex1 { gawk 'match($0,/'$1'/, ary) {print ary['${2:-'1'}']}'; }

لاستخدامه فقط

$ echo 'hello world' | regex1 'hello\s(.*)'
world




grep