I'm trying to port this function from zsh to generic POSIX shell script:
mcp () {
# run commands on a variety of searches (defaults to giving a count)
while read -u9 -n line ; do
command=`echo $line| sed 's/#.*$//'`
echo -n $command
eval "$command | ${*:-wc -l}"
done 9<<EOF
magrep "Precedence:bulk" # mass mails
magrep "broadcastSendId:.*" # mass mails
magrep "Feedback-ID:.*" # mass mails
EOF
}
The while loop uses file descriptor 9 instead of stdin, so that the commands within the loop can include commands that read from the function's stdin.
POSIX appears to allow the same redirection, but its 'read' does not have a "-u" option to take an alternative input fd, and I'm struggling to find a redirection command that works as a replacement.
Does anyone have an alternative to read -u for a POSIX version of this function?
Just open the read command each time with the file descriptor passed to stdin:
while read line <&9; do
echo "$line"
done 9<<'EOF'
magrep "Precedence:bulk" # mass mails
magrep "broadcastSendId:.*" # mass mails
magrep "Feedback-ID:.*" # mass mails
EOF
or more advanced example:
while
IFS= read -r line <&9
IFS=' ' read -r file2col1 file2col2 <&10
IFS=' ' read -r file3col1 file3col2 <&11
do
echo -----------
echo "$line"
echo "$file2col1"
echo "$file2col2"
echo "$file3col1"
echo "$file2col2"
done 9<<'EOF' 10<<EOF2 11<<'EOF3'
magrep "Precedence:bulk" # mass mails
magrep "broadcastSendId:.*" # mass mails
magrep "Feedback-ID:.*" # mass mails
EOF
file2 a
file2 b
file2 c
EOF2
file3 1
file3 2
file3 3
EOF3
If you want to read file line by line the idiomatic way, always set the IFS, so preserve leading and trailing whitespaces and use -r
option not to be surprised by \$
beeing expanded, so use:
while IFS= read -r line
Also the read command you posted will not work, because you have the -n
option, which isn't a POSIX option (and has different meanings in zsh and bash -- you're using the zsh version).
echo
which is not portable, but use printf.$(...)
instead, which allows for nesting.