简体   繁体   English

如何在Unix Bash脚本中用新行替换“\\ n”字符串

[英]How to replace “\n” string with a new line in Unix Bash script

Cannot seem to find an answer to this one online... 似乎无法在网上找到这个答案...

I have a string variable (externally sourced) with new lines "\\n" encoded as strings. 我有一个字符串变量(外部源),新行"\\n"编码为字符串。

I want to replace those strings with actual new line carriage returns. 我想用实际的新行回车替换这些字符串。 The code below can achieve this... 下面的代码可以达到这个目的......

echo $EXT_DESCR | sed 's/\\n/\n/g'

But when I try to store the result of this into it's own variable, it converts them back to strings 但是当我尝试将结果存储到它自己的变量中时,它会将它们转换回字符串

NEW_DESCR=`echo $EXT_DESCR | sed 's/\\n/\n/g'`

How can this be achieved, or what I'm I doing wrong? 如何实现这一目标,或者我做错了什么?

Here's my code I've been testing to try get the right results 这是我的代码,我一直在测试,以尝试获得正确的结果

EXT_DESCR="This is a text\nWith a new line"
echo $EXT_DESCR | sed 's/\\n/\n/g'

NEW_DESCR=`echo $EXT_DESCR | sed 's/\\n/\n/g'`
echo ""
echo "$NEW_DESCR"

No need for sed , using parameter expansion : 使用参数扩展不需要sed

$ foo='1\n2\n3'; echo "${foo//'\n'/$'\n'}"  
1
2
3

With bash 4.4 or newer, you can use the E operator in ${parameter@operator} : 使用bash 4.4或更新版本,您可以在${parameter@operator}使用E运算${parameter@operator}

$ foo='1\n2\n3'; echo "${foo@E}"
1
2
3

Other answers contain alternative solutions. 其他答案包含替代解决方案 (I especially like the parameter expansion one.) (我特别喜欢参数扩展一个。)

Here's what's wrong with your attempt: 这是你的尝试出了什么问题:

In

echo $EXT_DESCR | sed 's/\\n/\n/g'

the sed command is in single quotes, so sed gets s/\\\\n/\\n/g as is. sed命令是单引号,因此sed按原样获得s/\\\\n/\\n/g

In

NEW_DESCR=`echo $EXT_DESCR | sed 's/\\n/\n/g'`

the whole command is in backticks, so a round of backslash processing is applied. 整个命令在反引号中,因此应用了一轮反斜杠处理。 That leads to sed getting the code s/\\n/\\n/g , which does nothing. 这导致sed获得代码s/\\n/\\n/g ,它什么都不做。

A possible fix for this code: 此代码的可能修复:

NEW_DESCR=`echo $EXT_DESCR | sed 's/\\\\n/\\n/g'`

By doubling up the backslashes, we end up with the right command in sed. 通过加倍反斜杠,我们在sed中得到了正确的命令。

Or (easier): 或者(更容易):

NEW_DESCR=$(echo $EXT_DESCR | sed 's/\\n/\n/g')

Instead of backticks use $( ) , which has less esoteric escaping rules. 而不是反引号使用$( ) ,它具有较少深奥的逃避规则。

Note: Don't use ALL_UPPERCASE for your shell variables. 注意:不要将ALL_UPPERCASE用于shell变量。 UPPERCASE is (informally) reserved for system variables such as HOME and special built-in variables such as IFS or RANDOM . UPPERCASE (非正式地)保留用于系统变量,例如HOME和特殊的内置变量,例如IFSRANDOM

This printf would do the job by interpreting all escaped constructs: 这个printf可以通过解释所有转义的构造来完成工作:

printf -v NEW_DESCR "%b" "$EXT_DESCR"

-v option will store output in a variable so no need to use command substitution here. -v选项将输出存储在变量中,因此不需要在此处使用命令替换。

Problem with your approach is use of old back-ticks. 你的方法的问题是使用旧的后退。 You could do: 你可以这样做:

NEW_DESCR=$(echo "$EXT_DESCR" | sed 's/\\n/\n/g')

Assuming you're using gnu sed as BSD sed won't work with this approach. 假设您正在使用gnu sed作为BSD sed将无法使用此方法。

Depending on what exactly you need it for: 具体取决于您需要它:

echo -e $EXT_DESCR

might be all you need. 可能就是你所需要的一切。

From echo man page: 来自echo手册页:

-e enable interpretation of backslash escapes -e启用反斜杠转义的解释

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM