如何拆分bash中的多字符分隔符的string?

为什么不能使用下面的bash代码?

for i in $( echo "emmbbmmaaddsb" | split -t "mm" ) do echo "$i" done 

预期产出:

 e bb aaddsb 

既然你期待换行符,你可以简单地用换行符替换字符串中的所有mm实例。 在纯粹的本地bash中:

 in='emmbbmmaaddsb' sep='mm' printf '%s\n' "${in//$sep/$'\n'}" 

如果你想在更长的输入流上做这样的替换,那么使用awk可能会更好,因为bash的内置字符串操作不能很好地扩展到超过几千字节的内容。 在BashFAQ#21中给出的gsub_literal shell函数(backending到awk )是适用的:

 # Taken from http://mywiki.wooledge.org/BashFAQ/021 # usage: gsub_literal STR REP # replaces all instances of STR with REP. reads from stdin and writes to stdout. gsub_literal() { # STR cannot be empty [[ $1 ]] || return # string manip needed to escape '\'s, so awk doesn't expand '\n' and such awk -v str="${1//\\/\\\\}" -v rep="${2//\\/\\\\}" ' # get the length of the search string BEGIN { len = length(str); } { # empty the output string out = ""; # continue looping while the search string is in the line while (i = index($0, str)) { # append everything up to the search string, and the replacement string out = out substr($0, 1, i-1) rep; # remove everything up to and including the first instance of the # search string from the line $0 = substr($0, i + len); } # append whatever is left out = out $0; print out; } ' } 

在这方面,用作:

 gsub_literal "mm" $'\n' <your-input-file.txt >your-output-file.txt 

用bash:

 s="emmbbmmaaddsb" for i in "${s//mm/$'\n'}"; do echo "$i"; done 

输出:

 Ë
 BB
 aaddsb

推荐的字符s/regexp/replacement/工具是sed的命令s/regexp/replacement/对于一个正则表达式发生或全局s/regexp/replacement/g ,你甚至不需要一个循环或变量。

管你的echo输出,并尝试用换行符替换字符\n

echo "emmbbmmaaddsb" | sed 's/mm/\n/g'

输出是:

 e bb aaddsb