فصل ‎19‎-‏ Here Documentها

‎19.1‎-‏ Here Stringها

         یک ‎here string‎ می‌تواند به عنوان یک شکل حداقلی از ‎here document‎ در نظر گرفته شود.
         متشکل از چیزی بیش از COMMAND <<< $WORD نیست،
         که در آن ‎$WORD‎ بسط داده شده و به ورودی استاندارد COMMAND تغذیه می‌گردد.

به عنوان یک مثال ساده، این جایگزین ساختار ‎echo-grep‎ را در نظر بگیرید.

#  به جای:
if echo "$VAR" | grep -q txt   #  یا  ‎if [[ $VAR = *txt* ]]‎
# و غیره.

if grep -q "txt" <<< "$VAR"
#را امتحان کنید
then   #         ^^^
   echo "$VAR contains the substring sequence \"txt\""
fi
#با تشکر از ‎Sebastian Kaminski‎، به جهت پیشنهادش.

یا، در ترکیب با read:

String="This is a string of words."

read -r -a Words <<< "$String"
#گزینه ‎-a‎ برای ‎read‎ مقادیر نتیجه شده را
#+به عناصر متوالی یک آرایه اختصاص می‌دهد.

echo "First word in String is:    ${Words[0]}"   # This
echo "Second word in String is:   ${Words[1]}"   # is
echo "Third word in String is:    ${Words[2]}"   # a
echo "Fourth word in String is:   ${Words[3]}"   # string
echo "Fifth word in String is:    ${Words[4]}"   # of
echo "Sixth word in String is:    ${Words[5]}"   # words.
echo "Seventh word in String is:  ${Words[6]}"   # (null)
                                                 # Past end of $String.

#با تشکر از ‎Francisco Lobo‎ بابت پیشنهادش.

بی تردید، تغذیه نمودن خروجی یک ‎here string‎ به stdin یک حلقه امکان‌پذیر است.

#چنانکه ‎Seamus‎ اشاره می‌کند . . .

ArrayVar=( element0 element1 element2 {A..D} )

while read element ; do
  echo "$element" 1>&2
done <<< $(echo ${ArrayVar[*]})

# element0 element1 element2 A B C D

مثال ‎19-13‎. درج یک سطر در ابتدای یک فایل

#!/bin/bash
# ‎prepend.sh:‎   .افزودن متن در ابتدای فایل
#
#  مثال توسط ‎Kenny Stauffer‎ اهدا گردیده، و
#+به طور اندک توسط نگارنده ویرایش شده است.


E_NOSUCHFILE=85

read -p "File: " file   #شناسه ‎-p‎ برای read اعلان را نمایش می‌دهد.
if [ ! -e "$file" ]
then                    #  اگر چنین فایلی موجود نباشد، خارج شود.
  echo "File $file not found."
  exit $E_NOSUCHFILE
fi

read -p "Title: " title
cat - $file <<<$title > $file.new

echo "Modified file is $file.new"

exit                    #انتهای اجرای اسکریپت.
           :از ‎'man bash'‎
------------------------------------------
  Here Strings
  	A variant of here documents, the format is:
  
  		<<<word
  
  	The word is expanded and supplied to the command on its standard input.
------------------------------------------
  البته، مورد زیر نیز کار می‌کند‏:‏
   sed -e '1i\
   Title: ' $file

مثال ‎19-14‎. تجزیه یک صندوق پست

#!/bin/bash
#  اسکریپت به وسیله ‎Francisco Lobo‎ ارایه، و به طور جزئی
#+توسط نگارنده راهنمای ABS ویرایش و توضیح‌گذاری شده است.
#  با مجور در راهنمای ABS استفاده شده است. ‎(Thank you!)‎

#این اسکریپت تحت ‎Bash‎ نگارش کمتر از ‎3.0‎ اجرا نخواهد شد.


E_MISSING_ARG=87
if [ -z "$1" ]
then
  echo "Usage: $0 mailbox-file"
  exit $E_MISSING_ARG
fi

mbox_grep()  #تجزیه فایل mailbox
{
    declare -i body=0 match=0
    declare -a date sender
    declare mail header value


    while IFS= read -r mail
#         ^^^^       تنظیم مجدد ‎$IFS‎
#          وگرنه ‎read‎ فاصله را از ابتدا و انتهای ورودی‌اش حذف می‌کند.

do
	if [[ $mail =~ ^From  ]]   #مطابقت با فیلد «From» در پیغام.
		then
		(( body  = 0 ))         #        "صفر کردن" متغیرها.
		(( match = 0 ))
		unset date

	elif (( body ))
		then
		(( match ))
            #  echo "$mail"
            #اگر می‌خواهید تمام بدنه پیغام نمایش داده شود،
            #+   سطر فوق را از حالت توضیح بودن خارح کنید.

	elif [[ $mail ]]; then
		IFS=: read -r header value <<< "$mail"
      #                                    ^^^   here string

		case "$header" in
		[Ff][Rr][Oo][Mm] ) [[ $value =~ "$2" ]] && (( match++ )) ;;
      # مطابقت دادن سطر «From».
		[Dd][Aa][Tt][Ee] ) read -r -a date <<< "$value" ;;
      #                                            ^^^
      # انطباق سطر «Date».
		[Rr][Ee][Cc][Ee][Ii][Vv][Ee][Dd] ) read -r -a sender <<< "$value" ;;
      #                                                              ^^^
      # انطباق آدرس ‎IP‎ (می‌تواند تقلبی باشد).
		esac

	else
		(( body++ ))
		(( match  )) &&
		echo "MESSAGE ${date:+of: ${date[*]} }"
      #         تمام آرایه ‎$date‎                 ^
		echo "IP address of sender: ${sender[1]}"
      #  فیلد دوم سطرِ بازیابی شده                    ^

	fi


done < "$1"        # تغییر مسیر ‎stdout‎ فایل به حلقه.
}


mbox_grep "$1"     #   فرستادن فایل mailbox به تابع.

exit $?

#                               تمرین‌ها:
#                       -------------------------
#  ‎(1‎ تابع منفرد فوق را به منظور خوانایی بیشتر به چند تابع تبدیل کنید.
# ‎(2‎ برای بررسی کلیدواژه‌های مختلف، تجزیه بیشتری به اسکریپت اضافه کنید.

bash$ mailbox_grep.sh scam_mail
  MESSAGE of Thu, 5 Jan 2006 08:00:56 -0500 (EST) 
  IP address of sender: 196.3.62.4

تمرین: استفاده‌های دیگری برای ‎here stringها پیدا کنید، به عنوان مثال، مانند تغذیه ورودی به ‎dc‎.