在for循环中使用文字\ n分割字符串

时间:2017-06-08 15:58:31

标签: bash shell

请考虑此字符串: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帮助后,我结束了-rmysql命令,以原始格式获取结果。

现在我有了这个:

while IFS='' read -r permitted_sender
do
    # Do stuff
done <<<"$permitted_senders"

1 个答案:

答案 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来引用换行符。