我有以下变量。
echo "|$COMMAND|"
回来了
| REBOOT|
如何删除第一个换行符?
echo "|$COMMAND|"|tr '\n' ' '
将用空格替换换行符(在 POSIX/Unix 中它不是回车符)。
老实说,我会考虑从 bash 切换到一些更理智的东西。或者一开始就避免生成这种畸形数据。
嗯,这似乎也是一个可怕的安全漏洞,这取决于数据来自哪里。
通过删除所有换行符来清理变量:
COMMAND=$(echo $COMMAND|tr -d '\n')
tr命令可以由 // 抨击代替:
tr
//
COMMAND=$'\nREBOOT\r \n' echo "|${COMMAND}|" | OOT | echo "|${COMMAND//[$'\t\r\n']}|" |REBOOT | echo "|${COMMAND//[$'\t\r\n ']}|" |REBOOT|
请参阅 bash 手册页中的 参数展开和 引用:
man -Pless\ +/\/pattern bash man -Pless\ +/\\\'string\\\' bash man -Pless\ +/^\\\ *Parameter\\\ Exp bash man -Pless\ +/^\\\ *QUOTING bash
正如@AlexJordan 所要求的,这将抑制 所有指定的字符。
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|
注意: 为了使用 *(...)语法,Bash启用了 extglob选项(shopt -s extglob)。
*(...)
extglob
shopt -s extglob
如果您正在使用带有 extglobb 选项的 bash,您可以通过以下方式删除尾随的空格:
shopt -s extglob COMMAND=$'\nRE BOOT\r \n' echo "|${COMMAND%%*([$'\t\r\n '])}|"
产出:
| RE BOOT|
或者将%% 替换为 # # ,以仅替换前导空格。
使用 bash:
bash
echo "|${COMMAND/$'\n'}|"
(注意,这个问题中的控制字符是一个‘ newline’(\n) ,而不是回车符(\r) ; 后者将在一行中输出 REBOOT|。)
\n
\r
REBOOT|
使用 Bash 壳参数展开 ${parameter/pattern/string}:
${parameter/pattern/string}
模式被扩展以生成一个模式,就像在文件名扩展中一样。展开 参数,将 模式与其值的最长匹配替换为 绳子。[ ... ]如果 绳子为空,则删除 模式的匹配项,并且可以省略 模式之后的 /。
还使用 $'' ANSI-C 引用构造将换行指定为 $'\n'。直接使用换行符也可以,只是不那么漂亮:
$''
$'\n'
echo "|${COMMAND/ }|"
#!/bin/bash COMMAND="$'\n'REBOOT" echo "|${COMMAND/$'\n'}|" # Outputs |REBOOT|
或者,使用换行:
#!/bin/bash COMMAND=" REBOOT" echo "|${COMMAND/ }|" # Outputs |REBOOT|
对我有效的是 echo $testVar | tr "\n" " "
echo $testVar | tr "\n" " "
TestVar 包含变量/script-output 的位置
您可以简单地使用 echo -n "|$COMMAND|"。
echo -n "|$COMMAND|"
$ man echo
-n不输出尾部换行符
-n
添加答案以显示剥离多个字符(包括 r 使用 tr 和 sed)的示例。 并说明如何使用 hexdump。
在我的例子中,我发现以 awk print 结尾的命令行中最后一项 |awk '{print $2}'包含回车符 r 和引号。
|awk '{print $2}'
我使用 sed 's/["\n\r]//g'去掉了回车和引号。
sed 's/["\n\r]//g'
我也可以用 tr -d '"\r\n'。
tr -d '"\r\n'
值得注意的是,如果想要删除 n 个换行字符,就需要 sed -z。
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 |
这是相关的: 什么是回车、换行和换行?
为了解决实际问题的一个可能根源,您有可能正在寻找一个 crlf 文件。
CRLF 例子:
. env (crlf)
VARIABLE_A="abc" VARIABLE_B="def"
跑,嘘
#!/bin/bash source .env echo "$VARIABLE_A" echo "$VARIABLE_B" echo "$VARIABLE_A $VARIABLE_B"
返回:
abc def def
不过,如果你转换成 LF:
abc def abc def
可以使用 Grep 过滤掉任何空行。如果您有几行数据并且希望删除任何空的数据,那么这非常有用。
echo "$COMMAND" | grep .
简短的回答 是最好的(请更改)使用这个 bashism 如果你不想为这样一个简单的任务产生(tr,sed 或 awk)进程,bash 可以单独完成:
COMMAND=${COMMAND//$'\n'/}
来自文件:
${FOO//from/to} Replace all ${FOO/from/to} Replace first match
谢谢你的提醒,这是最好的答案。