请考虑此字符串:foo\nbar\nbaz
如何使用\ n作为分隔符将其拆分?
我没有运气就玩过IFS。
编辑:我想将其拆分为for循环。
好的,我会解释一下我的情况。
我需要使用存储在MySQL数据库中的数据来提供某个配置文件。
我从TEXT类型列中获取值。此列中的每条记录可以为空或多个电子邮件地址(foo@bar.tld),域名(bar.tld)或域名占位符,包括其子域(.bar.tld)。
按照设计,程序员决定这个字段应该是多行的,因此是分隔符。
我的工作是个性化地获取这些价值并将其加工。所以我迭代了值并为它们做了一些事情。
真正的问题是我得到一个两个字节的分隔符char就像这样:
foo@bar.tld\nfoo.tld\n.foo.tld
所以我无法单独访问每个元素。
我希望你现在能理解(英语不是我的母语)。
EDIT2:
现在我正在使用此代码解决问题:
PERMITTED_SENDERS="foo@bar.tld\nfoo.tld\n.foo.tld"
for SENDER in ${PERMITTED_SENDERS//'\n'/ }
do
if [[ "$SENDER" =~ @ ]]
then
printf "\tsender == $SENDER\n"
elif [[ "$SENDER" =~ ^\. ]]
then
printf "\tsender =~ [@|.]$(to_tld_domain $SENDER)\$\n"
else
printf "\tsender =~ \@$(to_regex $SENDER)\$\n"
fi
done
@ CharlesDuffy是for
循环仍然不好解决这个问题?
EDIT3
彻底阅读mysql帮助后,我结束了-r
到mysql
命令,以原始格式获取结果。
现在我有了这个:
while IFS='' read -r permitted_sender
do
# Do stuff
done <<<"$permitted_senders"
答案 0 :(得分:4)
for
循环是这项工作的错误工具。请考虑使用while
循环:
str='foo\nbar\nbaz'
while [[ $str ]]; do # iterate as long as we have input
if [[ $str = *'\n'* ]]; then # if there's a '\n' sequence later...
first=${str%%'\n'*} # put everything before it into 'first'
rest=${str#*'\n'} # and put everything after it in 'rest'
else # if there's no '\n' later...
first=$str # then put the whole rest of the string in 'first'
rest='' # and there is no 'rest'
fi
echo "Processing piece: $first"
str=$rest
done
这恰当地发出:
Processing piece: foo
Processing piece: bar
Processing piece: baz
那就是说,如果必须使用for
循环:
str='foo\nbar\nbaz'
set -f # disable globbing
printf -v str_literal '%b' "$str" # replace '\n' with a literal newline
IFS=$'\n' read -r -a pieces <<<"$str_literal" # split on literal newlines
for piece in "${pieces[@]}"; do # iterate over the pieces
echo "Processing piece: $piece"
done
请注意,这并非没有副作用 - 例如,它会用文字标签替换\t
序列。我假设这就是您真正想要的,因为您的数据存储使用\n
来引用换行符。