如何从Bash中的字符串中删除换行符

时间:2013-10-13 13:40:19

标签: bash variables

我有以下变量。

echo "|$COMMAND|"

返回

|
REBOOT|

如何删除第一个换行符?

9 个答案:

答案 0 :(得分:89)

下,有一些基本原则:

tr命令可以替换为// bashism

COMMAND=$'\nREBOOT\r   \n'
echo "|${COMMAND}|"
|
   OOT
|

echo "|${COMMAND//[$'\t\r\n']}|"
|REBOOT   |

echo "|${COMMAND//[$'\t\r\n ']}|"
|REBOOT|

请参阅bash手册页中的参数扩展 QUOTING

man -Pless\ +/\/pattern bash
man -Pless\ +/\\\'string\\\' bash

man -Pless\ +/^\\\ *Parameter\\\ Exp bash
man -Pless\ +/^\\\ *QUOTING bash

此外...

正如@AlexJordan所说,这将禁止所有指定的字符。那么如果$COMMAND确实包含空格......

COMMAND=$'         \n        RE BOOT      \r           \n'
echo "|$COMMAND|"
|
           BOOT      
|

CLEANED=${COMMAND//[$'\t\r\n']}
echo "|$CLEANED|"
|                 RE BOOT                 |

shopt -q extglob || { echo "Set shell option 'extglob' on.";shopt -s extglob;}

CLEANED=${CLEANED%%*( )}
echo "|$CLEANED|"
|                 RE BOOT|

CLEANED=${CLEANED##*( )}
echo "|$CLEANED|"
|RE BOOT|

不久:

COMMAND=$'         \n        RE BOOT      \r           \n'
CLEANED=${COMMAND//[$'\t\r\n']} && CLEANED=${CLEANED%%*( )}
echo "|${CLEANED##*( )}|"
|RE BOOT|

注意:要启用extglob选项(shopt -s extglob),以便使用*(...)语法。

答案 1 :(得分:71)

echo "|$COMMAND|"|tr '\n' ' '

将用空格替换换行符(在POSIX / Unix中它不是回车符。)

说实话,我会考虑从bash转向更健全的东西。或者首先避免生成这种格式错误的数据。

嗯,这似乎也可能是一个可怕的安全漏洞,取决于数据的来源。

答案 2 :(得分:57)

通过删除所有回车来清理变量:

COMMAND=$(echo $COMMAND|tr -d '\n')

答案 3 :(得分:5)

使用bash

echo "|${COMMAND/$'\n'}|"

(请注意,此问题中的控制字符是'换行符'(\n),而不是回车符(\r);后者将输出REBOOT|在一条线上。)

解释

使用Bash Shell Parameter Expansion ${parameter/pattern/string}

  

扩展模式以生成模式,就像在文件名扩展中一样。 参数已展开, pattern 与其值的最长匹配将替换为 string 。 [...]如果 string 为null,则删除 pattern 的匹配项,并且 pattern 之后的 / 可能是删去。

还使用$'' ANSI-C quoting构造将换行符指定为$'\n'。直接使用换行也可以,但不太漂亮:

echo "|${COMMAND/
}|"

完整示例

#!/bin/bash
COMMAND="$'\n'REBOOT"
echo "|${COMMAND/$'\n'}|"
# Outputs |REBOOT|

或者,使用换行符:

#!/bin/bash
COMMAND="
REBOOT"
echo "|${COMMAND/
}|"
# Outputs |REBOOT|

答案 4 :(得分:2)

如果您在启用了extglob选项的情况下使用bash,则可以通过以下方式删除尾随空格:

shopt -s extglob
COMMAND=$'\nRE BOOT\r   \n'
echo "|${COMMAND%%*([$'\t\r\n '])}|"

输出:

|
RE BOOT|

或者用##替换%%以仅替换前导空格。

答案 5 :(得分:2)

您可以简单地使用echo -n "|$COMMAND|"

答案 6 :(得分:2)

添加答案以显示使用tr和sed剥离多个字符(包括\ r)的示例。 并说明了如何使用hexdump。

在我的情况下,我发现以awk打印该行中最后一个项目|awk '{print $2}'结尾的命令包含回车符\ r以及引号。

我用sed 's/["\n\r]//g'去除了回车和引号。

我也可以使用tr -d '"\r\n'

如果要删除\ n换行符,则需要注意sed -z

$ COMMAND=$'\n"REBOOT"\r   \n'

$ echo "$COMMAND" |hexdump -C
00000000  0a 22 52 45 42 4f 4f 54  22 0d 20 20 20 0a 0a     |."REBOOT".   ..|

$ echo "$COMMAND" |tr -d '"\r\n' |hexdump -C
00000000  52 45 42 4f 4f 54 20 20  20                       |REBOOT   |

$ echo "$COMMAND" |sed 's/["\n\r]//g' |hexdump -C
00000000  0a 52 45 42 4f 4f 54 20  20 20 0a 0a              |.REBOOT   ..|

$ echo "$COMMAND" |sed -z 's/["\n\r]//g' |hexdump -C
00000000  52 45 42 4f 4f 54 20 20  20                       |REBOOT   |

这是相关的: What are carriage return, linefeed, and form feed?

  • CR == \ r == 0x0d
  • LF == \ n == 0x0a

答案 7 :(得分:2)

为了解决实际问题的一个可能根源,您可能正在采购 crlf 文件。

CRLF 示例:

.env (crlf)

VARIABLE_A="abc"
VARIABLE_B="def"

运行.sh

#!/bin/bash
source .env
echo "$VARIABLE_A"
echo "$VARIABLE_B"
echo "$VARIABLE_A $VARIABLE_B"

返回:

abc
def
 def

如果您转换为 LF:

.env (lf)

VARIABLE_A="abc"
VARIABLE_B="def"

运行.sh

#!/bin/bash
source .env
echo "$VARIABLE_A"
echo "$VARIABLE_B"
echo "$VARIABLE_A $VARIABLE_B"

返回:

abc
def
abc def

答案 8 :(得分:1)

对我有用的是echo $testVar | tr "\n" " "

其中testVar包含我的变量/ script-output