إرجاع مباراة Regex في برنامج نصي باش، بدلا من استبداله

StackOverflow https://stackoverflow.com/questions/1898553

  •  19-09-2019
  •  | 
  •  

سؤال

أريد فقط مطابقة بعض النص في برنامج نصي باش، حاولت استخدام SED، لكنني لا أستطيع أن أجعلها مجرد إخراج المباراة بدلا من استبدالها بشيء ما.

echo -E "TestT100String" | sed 's/[0-9]+/dontReplace/g'

والتي سوف تخرج: testddontreplackestring

وهو ليس ما أريده، أريده إخراج: 100

من الناحية المثالية أريد أن أضع كل المباريات في صفيف.

تحرير: إدخال النص يأتي في سلسلة:

newName()
{
 #Get input from function
 newNameTXT="$1"

 if [[ $newNameTXT ]]; then
 #Use code that im working on now, using the $newNameTXT string.

 fi
} 
هل كانت مفيدة؟

المحلول

echo "TestT100String" | sed 's/[^0-9]*\([0-9]\+\).*/\1/'

echo "TestT100String" | grep -o  '[0-9]\+'

تعتمد الطريقة التي تستخدمها لوضع النتائج في صفيف إلى حد ما في كيفية استرجاع البيانات الفعلية. لا توجد معلومات كافية في سؤالك لتكون قادرا على توجيهك جيدا. ومع ذلك، وهنا طريقة واحدة:

index=0
while read -r line
do
    array[index++]=$(echo "$line" | grep -o  '[0-9]\+')
done < filename

هنا طريقة أخرى:

array=($(grep -o '[0-9]\+' filename))

نصائح أخرى

يمكنك القيام بذلك بحتة في باش باستخدام قوس مربع مزدوج [[ ]] اختبار المشغل، الذي ينتج عنه المتاجر في صفيف يسمى BASH_REMATCH:

[[ "TestT100String" =~ ([0-9]+) ]] && echo "${BASH_REMATCH[1]}"

نقي سحق. وبعد استخدام استبدال المعلمة (لا توجد عمليات وبيئة خارجية):

string="TestT100String"

echo ${string//[^[:digit:]]/}

يزيل جميع غير أرقام.

استخدام grep. SED هو محرر. إذا كنت ترغب فقط في مطابقة Regoxp، فإن Grep هو أكثر من كافية.

باستخدام awk.

linux$ echo -E "TestT100String" | awk '{gsub(/[^0-9]/,"")}1'
100

لا أعرف لماذا لا أحد يستخدم expr: إنه محمول وسهل.

newName()
{
 #Get input from function
 newNameTXT="$1"

 if num=`expr "$newNameTXT" : '[^0-9]*\([0-9]\+\)'`; then
  echo "contains $num"
 fi
}

أعلم أن هذا موضوع قديم، لكنني جئت إليها نفس عمليات البحث ووجدت احتمالا رائعا آخر تطبيق Regex على سلسلة / متغير باستخدام Grep:

# Simple
$(echo "TestT100String" | grep -Po "[0-9]{3}")
# More complex using lookaround
$(echo "TestT100String" | grep -Po "(?i)TestT\K[0-9]{3}(?=String)")

مع استخدام إمكانيات Lookaround، يمكن تمديد تعبيرات البحث للحصول على مطابقة أفضل. أين (?i) يشير إلى النمط قبل النمط البحث (LookAhead)،\K يشير إلى نمط البحث الفعلي و (?=) يحتوي على النمط بعد البحث (lookbehind).

https://www.regular-expressions.info/lookaround.html.

المثال المحدد يطابق نفس PCRE Regex TestT([0-9]{3})String

حسنا، يحل SED مع S / "Pattern1" / "Pattern2" / G يستبدل جميع الأنماط على مستوى العالم إلى نمط 2.

إلى جانب ذلك، SED بينما افتراضيا طباعة السطر بأكمله افتراضيا. أقترح أنابيب التعليمة بأمر قطع وتحاول استخراج الأرقام التي تريدها:

إذا كنت تبدو فقط لاستخدام SED ثم استخدم Tre:

sed -n 's/.*\(0-9\)\(0-9\)\(0-9\).*/\1,\2,\3/g'.

أحاول وتنفيذ الأمر أعلاه حتى تأكد من أن بناء الجملة صحيح. نأمل أن هذا ساعد.

باستخدام قذيفة باش فقط

declare -a array
i=0
while read -r line
do
        case "$line" in
            *TestT*String* )
            while true
            do
                line=${line#*TestT}
                array[$i]=${line%%String*}
                line=${line#*String*}
                i=$((i+1))
                case "$line" in
                    *TestT*String* ) continue;;
                    *) break;;
                esac
            done
            esac
done <"file"
echo ${array[@]}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top