两个看似相同的字符串,但换行符不等。

问题描述 投票:1回答:2

我试图使用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报告这些字符串是相等的。

bash sed newline
2个回答
1
投票

在对我的问题的评论的提示下,我设法找出了发生了什么。我当时专注于想出一个有效的sed表达式,并确保了 result 是正确的,以至于我没有注意到。expected 字符串不正确。

  1. 为了使用 \n 字符串中的换行符,你必须使用 $'one\ntwo\nthree' 句法--见 如何在sh中的字符串中出现换行? 的其他解决方案。
  2. 我是针对bash 3.2.57版本(Mac OS 10.14.6自带的版本)开发的。当使用 expected="one\ntwo\nthree" 然后回声,它们在控制台中显示为换行符。新版本的bash将这些字符串显示为转义字符--所以我认为这是一个bash以后版本中已经修正的错误。

0
投票

对于诊断看似相同的字符串,可以尝试将并排的 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

0
投票

多了一个新的行字符 \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 启用反斜杠转义的解释。

© www.soinside.com 2019 - 2024. All rights reserved.