Bash از تعداد تعجبآوری عملیات دستکاری رشتهها پشتیبانی میکند. متاسفانه، این ابزارها فاقد یک کانون یکپارچه هستند. بعضی از آنها زیر مجموعهای از جایگزینی پارامتر هستند، و برخی دیگر مشمول تواناییهای فرمان expr یونیکس میشوند. این مطلب به ناسازگاری ترکیب دستوری فرمان و تداخل توانایی منجر میگردد، نه به اختلال یادآوری.
طول رشته
مثال 10-1. درج یک سطر خالی بین پاراگرافها در یک فایل متن
#!/bin/bash # # # # MINLEN=60 # #فرض کنید سطرهای کوتاهتر از $MINLEN کاراکتر که با یک نقطه ختم #+میشوند، یک پاراگراف را خاتمه میدهند. تمرینهای زیر را ببینید. while read line # do echo "$line" # len=${#line} if [[ "$len" -lt "$MINLEN" && "$line" =~ [*{\.}]$ ]] # #یک بهروزرسانی برای Bash نگارش قبلی این اسکریپت را نقض کرد. آخ! #با تشکر از Halim Srama برای اشاره به این مورد و پیشنهاد اصلاحیه. then echo # fi #+ done exit # # --------- #اسکریپت معمولاً یک سطر خالی در انتهای فایل هدف 1) #+اضافه میکند. این مورد را اصلاح کنید. #سطر 17 فقط نقطه را به عنوان خاتمهدهنده در نظر 2) #میگیرد. این مورد را ویرایش کنید تا سایر کاراکترهای #+انتهای جمله از قبیل ?، !، و " را نیز شامل شود.
طول رشته فرعی مطابقت یافته از ابتدای رشته
$substring یک عبارت منظم است.
$substring یک عبارت منظم است.
stringZ=abcABC123ABCabc # # echo `expr match "$stringZ" 'abc[A-Z]*.2'` # echo `expr "$stringZ" : 'abc[A-Z]*.2'` #
Index
شماره اولین موقعیتی در $string که کاراکتری از $substring نخست در آنجا منطبق میشود.
stringZ=abcABC123ABCabc # echo `expr index "$stringZ" C12` # # echo `expr index "$stringZ" 1c` # #'c' (در موقعیت شماره 3 ) قبل از '1' منطبق میشود.
این معادل تقریبی strchr() در C است.
استخراج رشته فرعی
رشته فرعی از موقعیت $position تا انتهای رشته $string استخراج میکند.
اگر به جای string کاراکتر * یا @ قرار گیرد، آنوقت این ترکیب، پارامترهای مکانی را با شروع از پارامتر شماره $position استخراج میکند.[1]
یک رشته فرعی به طول $length کاراکتر از محل $position از رشته $string استخراج میکند.
stringZ=abcABC123ABCabc # # echo ${stringZ:0} # echo ${stringZ:1} # echo ${stringZ:7} # echo ${stringZ:7:3} # # # echo ${stringZ:-4} # #رشته کامل، همچون در ${parameter:-default} تعبیر میکند. # echo ${stringZ:(-4)} # echo ${stringZ: -4} # # #پرانتزها یا فاصله اضافه شده پارامتر موقعیت را پوشش میدهند. #با تشکر از Dan Jacobson برای روشن کردن این مطلب.
شناسههای position و length میتوانند «پارامتری» بشوند، یعنی به جای یک ثابت عددی به صورت یک متغیر بیان گردند.
مثال 10-2. تولید یک رشته «تصادفی» ۸ کاراکتری
#!/bin/bash # # if [ -n "$1" ] # then #+ str0="$1" else #وگرنه از PID اسکریپت به عنوان رشته شروع استفاده شود. str0="$$" fi POS=2 #شروع از موقعیت 2 در رشته. LEN=8 # str1=$( echo "$str0" | md5sum | md5sum ) #درهم آمیختن دوگانه ^^^^^^ ^^^^^^ #+ randstring="${str1:$POS:$LEN}" #اینها میتوانند پارامتر باشند ^^^^ ^^^^ echo "$randstring" exit $? # # # #+
اگر به جای string کاراکتر * یا @ قرار گیرد، آنوقت این ترکیب، حداکثر به تعداد $length پارامتر مکانی را با شروع از پارامتر شماره $position استخراج میکند.
echo ${*:2} # echo ${@:2} # echo ${*:2:3} #
تعداد $length کاراکتر از رشته $string با شروع از محل $position استخراج میکند.
stringZ=abcABC123ABCabc # # echo `expr substr $stringZ 1 2` # echo `expr substr $stringZ 4 3` #
$substring را از ابتدای رشته $string استخراج میکند، که در اینجا $substring یک عبارت منظم است.
$substring در ابتدای رشته $string را استخراج میکند، که $substring یک عبارت منظم است.
stringZ=abcABC123ABCabc # echo `expr match "$stringZ" '\(.[b-c]*[A-Z]..[0-9]\)'` # echo `expr "$stringZ" : '\(.[b-c]*[A-Z]..[0-9]\)'` # echo `expr "$stringZ" : '\(.......\)'` # #
$substring را از انتهای رشته $string استخراج میکند، که $substring در آن یک عبارت منظم است.
$substring را از انتهای رشته $string استخراج میکند، که در آن $substring یک عبارت منظم است.
stringZ=abcABC123ABCabc # echo `expr match "$stringZ" '.*\([A-C][A-C][A-C][a-c]*\)'` # echo `expr "$stringZ" : '.*\(......\)'` #
پاک کردن رشته فرعی
کوتاهترین انطباق $substring را از جلوی $string حذف میکند.
بلندترین مورد انطباق $substring را از جلوی رشته $string حذف میکند.
stringZ=abcABC123ABCabc # # echo ${stringZ#a*C} # #پاک کردن کوتاهترین مورد انطباق بین 'a' و 'C'. echo ${stringZ##a*C} # #پاک کردن بلندترین مورد انطباق بین 'a' و 'C'. # X='a*C' echo ${stringZ#$X} # echo ${stringZ##$X} # #
کوتاهترین مورد انطباق $substring را از انتهای $string حذف میکند.
برای مثال:
#تغییر تمام پسوندهای «TXT» فایلهای داخل $PWD با پسوند «txt» #به عنوان مثال، "file1.TXT" میشود "file1.txt" . . . SUFF=TXT suff=txt for i in $(ls *.$SUFF) do mv -f $i ${i%.$SUFF}.$suff # #+الگوی منطبق شده از سمت راست متغیر $i . . . done ### #با تشکر از Rory Winston
طولانیترین مورد تطبیق $substring از انتهای رشته $string حذف میشود.
stringZ=abcABC123ABCabc # # echo ${stringZ%b*c} # #کوتاهترین مورد انطباق بین 'b' و 'c' با انتهای رشته $stringZ را پاک میکند. echo ${stringZ%%b*c} # #بلندترین مورد تطبیق بین 'b' و 'c' با انتهای رشته $stringZ را پاک میکند.
این عامل برای تولید نام فایلها سودمند است.
مثال 10-3. تبدیل قالب فایلهای گرافیکی، با تغییر نام فایل
#!/bin/bash # #تمام فایهای تصویری MacPaint در یک دایرکتوری را به قالب "pbm" تبدیل میکند. #برنامه "macptopbm" از بسته "netpbm" را به کار میبرد، که توسط #+Brian Henderson (bryanh@giraffe-data.com) پشتیبانی میشود. #Netpbm یک بخش استاندارد اکثر توزیعهای لینوکس است. OPERATION=macptopbm SUFFIX=pbm # if [ -n "$1" ] then directory=$1 # else directory=$PWD # fi #فرض میکند تمام فایلها در دایرکتوری هدف فایلهای تصویری #+MacPaint با یک پسوند نام فایل به صورت .mac هستند. for file in $directory/* # do filename=${file%.*c} #زدودن پسوند .mac از نام فایل #+('.*c' با هر چیزی بین '.' و 'c' #+و شامل خود آنها، منطبق میشود). $OPERATION $file > "$filename.$SUFFIX" # rm -f $file # echo "$filename.$SUFFIX" # done exit 0 # # ----------- # #آن را ویرایش کنید که «فقط» بر فایلهای دارای پسوند ".mac" عمل کند. # # #!/bin/bash # #فرض میکند imagemagick نصب شده است (استانداردِ اکثر توزیعهای لینوکس). INFMT=png #میتواند tif، jpg، gif، و غیره باشد. OUTFMT=pdf #میتواند tif، jpg، gif، pdf، و غیره باشد. for pic in *"$INFMT" do p2=$(ls "$pic" | sed -e s/\.$INFMT//) # convert "$pic" $p2.$OUTFMT done exit $?
مثال 10-4. تبدیل فایلهای صوتی جریانی به ogg
#!/bin/bash #ra2ogg.sh: تبدیل فایلهای صوتی جریانی (*.ra) به ogg. #از برنامه پخش صوتی وتصویری "mplayer" استفاده میکند: # #فایلهای کتابخانه "ogg" و "oggenc" را به کار میبرد: # # #این اسکریپت ممکن است به codecهای نصب شده مناسب از قبیل sipr.so #و همچنین احتمالاً به بسته compat-libstdc++ نیاز داشته باشد. OFILEPREF=${1%%ra} #زدودن پسوند "ra" OFILESUFF=wav #پسوند برای فایل wav OUTFILE="$OFILEPREF""$OFILESUFF" E_NOARGS=85 if [ -z "$1" ] # then echo "Usage: `basename $0` [filename]" exit $E_NOARGS fi ########################################################################## mplayer "$1" -ao pcm:file=$OUTFILE oggenc "$OUTFILE" #پسوند صحیح فایل به طور خودکار توسط oggenc اضافه شده. ########################################################################## rm "$OUTFILE" #حذف فایل واسطه *.wav # exit $? #نکته: # #در یک وبسایت، معمولاً به آسانی با کلیک روی یک فایل صوتی #+جریانی *.ram فقط آدرس URL فایل صوتی واقعی *.ra دریافت #میشود. سپس شما میتوانید با "wget" یا موردی مشابه آن، خود #+فایل *.ra را دانلود نمایید. #تمرینها # #مطابق معمول، اسکریپت فقط نام فایلهای *.ra را تبدیل میکند. با اجازهِ #استفاده از *.ram و سایر نام فایلها، قابلیت انعطاف آن را افزایش بدهید. # # #+ #یک URL مشخص شده، دانلود دستهای فایلهای صوتی جریانی #+(با استفاده از wget) و تبدیل درجای آنها.
یک شبیهسازی ساده از getopt با استفاده از ساختارهای استخراج رشته فرعی.
#!/bin/bash # #مولف: Chris Morgan #با مجوز در این راهنما استفاده شده است . getopt_simple() { echo "getopt_simple()" echo "Parameters are '$*'" until [ -z "$1" ] do echo "Processing parameter of: '$1'" if [ ${1:0:1} = '/' ] then tmp=${1:1} #از بین بردن '/' مقدم parameter=${tmp%%=*} # value=${tmp##*=} # echo "Parameter: '$parameter', value: '$value'" eval $parameter=$value fi shift done } #عبور دادن تمام گزینهها به getopt_simple() getopt_simple $* echo "test is '$test'" echo "test2 is '$test2'" exit 0 #اسکریپت UseGetOpt.sh را نیز ببینید، نگارش اصلاح شدهِ این اسکریپت است. --- sh getopt_example.sh /test=value1 /test2=value2 Parameters are '/test=value1 /test2=value2' Processing parameter of: '/test=value1' Parameter: 'test', value: 'value1' Processing parameter of: '/test2=value2' Parameter: 'test2', value: 'value2' test is 'value1' test2 is 'value2'
تعویض رشته فرعی
اولین مورد از مطابقت رشته فرعی $substring را با $replacement تعویض میکند. [2]
تعویض زیر-رشته $substring با $replacement.
stringZ=abcABC123ABCabc echo ${stringZ/abc/xyz} # #اولین مورد انطباق 'abc' را با 'xyz' تعویض میکند. echo ${stringZ//abc/xyz} # #تمام موارد منطبق با 'abc' را با 'xyz' تعویض میکند. echo --------------- echo "$stringZ" # echo --------------- # # match=abc repl=000 echo ${stringZ/$match/$repl} # # echo ${stringZ//$match/$repl} # # echo #در صورتیکه رشته $replacement ارایه نشود، چه اتفاقی رخ میدهد؟ echo ${stringZ/abc} # echo ${stringZ//abc} # #
اگر $substring با بخشی از ابتدای $string مطابقت کند، $replacement جایگزین $substring میگردد.
اگر $substring با قسمت انتهایی $string منطبق باشد، $replacement جایگزین $substring میشود.
stringZ=abcABC123ABCabc echo ${stringZ/#abc/XYZ} # #مورد انطباق پیشانی 'abc' را با 'XYZ' تعویض میکند. echo ${stringZ/%abc/XYZ} # #انطباق پایانی 'abc' را با 'XYZ' تعویض میکند.
یک اسکریپت Bash میتواند وسایل دستکاری رشته awk را به عنوان جایگزین کاربرد عملیات داخلیاش، فراخوانی نماید.
مثال 10-6. روشهای جایگزین استخراج و جایگزینی رشتههای فرعی
#!/bin/bash # String=23skidoo1 # # # #Bash کاراکتر اول رشته را به عنوان 0 شمارهگذاری میکند. #Awk اولین کاراکتر رشته را به عنوان 1 شمارهگذاری میکند. echo ${String:2:4} #مکان سوم (0-1-2) , طول 4 کاراکتر # #معادل ${string:pos:length} در awk برابر با substr(string,pos,length) است. echo | awk ' { print substr("'"${String}"'",3,4) # } ' #لولهکشی یک "echo" خالی به awk ورودی زائدی به آن میدهد، و #+ echo "----" # echo | awk ' { print index("'"${String}"'", "skid") # } #(skid در موقعیت 3 شروع میشود) ' #معادل awk از "expr index" ... exit 0
برای آشتایی بیشتر با دستکاری رشته در اسکریپتها، به بخش 10.2 و بخش مربوط به فرمان expr مراجعه کنید.
اسکریپتهای نمونه:
[1] | این در مورد شناسههای خط فرمان یا پارامترهای عبور داده شده به یک تابع صدق میکند. |
[2] | توجه نمایید که $substring و $replacement بر اساس مضمون میتوانند به رشتههای لفظی یا متغیرها اشاره کنند. |