إرجاع مباراة Regex في برنامج نصي باش، بدلا من استبداله
سؤال
أريد فقط مطابقة بعض النص في برنامج نصي باش، حاولت استخدام 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[@]}