我试图使用bash和sed将一个由逗号分隔的引号字符串列表转换为由换行符分隔的字符串列表。
下面是一个我正在做的例子。
#!/bin/bash
comma_to_newline() {
sed -En $'s/[ \t]*"([^"]*)",?[ \t]*/\\1\\\n/gp'
}
input='"one","two","three"'
expected="one\ntwo\nthree"
result="$( echo "${input}" | comma_to_newline )"
echo "Expected: <${expected}>"
echo "Result: <${result}>"
if [ "${result}" = "${expected}" ]; then
echo "EQUAL!"
else
echo "NOT EQUAL!"
fi
我得到的结果是:
Expected: <one
two
three>
Result: <one
two
three>
NOT EQUAL!
我知道这和换行符有关 但我不知道是什么意思 如果我把换行符换成其他字符串,如 XXX
我想把一个由逗号分隔的字符串列表转换成一个由换行符分隔的字符串列表,但工作正常,而且bash报告这些字符串是相等的。
在对我的问题的评论的提示下,我设法找出了发生了什么。我当时专注于想出一个有效的sed表达式,并确保了 result
是正确的,以至于我没有注意到。expected
字符串不正确。
\n
字符串中的换行符,你必须使用 $'one\ntwo\nthree'
句法--见 如何在sh中的字符串中出现换行? 的其他解决方案。expected="one\ntwo\nthree"
然后回声,它们在控制台中显示为换行符。新版本的bash将这些字符串显示为转义字符--所以我认为这是一个bash以后版本中已经修正的错误。对于诊断看似相同的字符串,可以尝试将并排的 diff
每行一个字符的输出 hexdump
格式。 替换为:
else
echo "NOT EQUAL!"
fi
...改为:
else
echo "NOT EQUAL!"
diff -y \
<(hexdump -v -e '/1 "%_ad# "' -e '/1 " _%_u\_\n"' <<< "${expected}") \
<(hexdump -v -e '/1 "%_ad# "' -e '/1 " _%_u\_\n"' <<< "${result}")
fi
多了一个新的行字符 \n
从你的函数中返回的字符串。
八进制转储
$echo '"one","two","three"' | sed -En $'s/[ \t]*"([^"]*)",?[ \t]*/\\1\\\n/gp' | od -c
0000000 o n e \n t w o \n t h r e e \n \n
0000017
$echo "one\ntwo\nthree" | od -c
0000000 o n e \ n t w o \ n t h r e e \n
0000020
$
另外,使用 echo -e
$echo "one\ntwo\nthree"
one\ntwo\nthree
$echo -e "one\ntwo\nthree"
one
two
three
$
来自 man
网页
-e 启用反斜杠转义的解释。