一个 here 字符串 可以被认为是 here document 的一种简化形式。
它仅仅包含 COMMAND <<< $WORD,
其中 $WORD 会被扩展,然后作为 stdin 传递给 COMMAND。
作为一个简单的例子,可以考虑用它来替代 echo-grep 结构。
# Instead of: if echo "$VAR" | grep -q txt # if [[ $VAR = *txt* ]] # etc. # Try: if grep -q "txt" <<< "$VAR" then # ^^^ echo "$VAR contains the substring sequence \"txt\"" fi # Thank you, Sebastian Kaminski, for the suggestion. |
或者,结合 read 使用
String="This is a string of words."
read -r -a Words <<< "$String"
# The -a option to "read"
#+ assigns the resulting values to successive members of an array.
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.
# Thank you, Francisco Lobo, for the suggestion. |
当然,也可以把 here 字符串 的输出传递给stdin的 循环。
# As Seamus points out . . .
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: Add text at beginning of file. # # Example contributed by Kenny Stauffer, #+ and slightly modified by document author. E_NOSUCHFILE=85 read -p "File: " file # -p arg to 'read' displays prompt. if [ ! -e "$file" ] then # Bail out if no such file. 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 # Ends script execution. from '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. Of course, the following also works: sed -e '1i\ Title: ' $file |
示例 19-14. 解析邮箱
#!/bin/bash
# Script by Francisco Lobo,
#+ and slightly modified and commented by ABS Guide author.
# Used in ABS Guide with permission. (Thank you!)
# This script will not run under Bash versions -lt 3.0.
E_MISSING_ARG=87
if [ -z "$1" ]
then
echo "Usage: $0 mailbox-file"
exit $E_MISSING_ARG
fi
mbox_grep() # Parse mailbox file.
{
declare -i body=0 match=0
declare -a date sender
declare mail header value
while IFS= read -r mail
# ^^^^ Reset $IFS.
# Otherwise "read" will strip leading & trailing space from its input.
do
if [[ $mail =~ ^From ]] # Match "From" field in message.
then
(( body = 0 )) # "Zero out" variables.
(( match = 0 ))
unset date
elif (( body ))
then
(( match ))
# echo "$mail"
# Uncomment above line if you want entire body
#+ of message to display.
elif [[ $mail ]]; then
IFS=: read -r header value <<< "$mail"
# ^^^ "here string"
case "$header" in
[Ff][Rr][Oo][Mm] ) [[ $value =~ "$2" ]] && (( match++ )) ;;
# Match "From" line.
[Dd][Aa][Tt][Ee] ) read -r -a date <<< "$value" ;;
# ^^^
# Match "Date" line.
[Rr][Ee][Cc][Ee][Ii][Vv][Ee][Dd] ) read -r -a sender <<< "$value" ;;
# ^^^
# Match IP Address (may be spoofed).
esac
else
(( body++ ))
(( match )) &&
echo "MESSAGE ${date:+of: ${date[*]} }"
# Entire $date array ^
echo "IP address of sender: ${sender[1]}"
# Second field of "Received" line ^
fi
done < "$1" # Redirect stdout of file into loop.
}
mbox_grep "$1" # Send mailbox file to function.
exit $?
# Exercises:
# ---------
# 1) Break the single function, above, into multiple functions,
#+ for the sake of readability.
# 2) Add additional parsing to the script, checking for various keywords.
$ 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 字符串 的其他用法,例如,向 dc 传递输入。