F. *_*uri 105

在,有一些基本原则:

该tr命令可以用// bashism代替:

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

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

echo "|${COMMAND//[$'\t\r\n ']}|"
|REBOOT|
Run Code Online (Sandbox Code Playgroud)

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

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

man -Pless\ +/^\\\ *Parameter\\\ Exp bash
man -Pless\ +/^\\\ *QUOTING bash
Run Code Online (Sandbox Code Playgroud)

进一步...

正如@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|
Run Code Online (Sandbox Code Playgroud)

不久:

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

注意:可以extglob选择启用(shopt -s extglob)以使用*(...)语法.

  • 那应该是最好的答案! (5认同)
  • 请注意,它还从字符串中删除了 *internal* 空格...... `COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n ']}|"` 返回 `|REBOOT|` (2认同)
  • @AlexJordan是的,这是一个*想要的功能*:你可以在`\n`之后删除空格以防止这种情况:`COMMAND ="RE BOOT"; echo"| $ {COMMAND // [$'\ t\r \n']} |"`将返回`| RE BOOT |`. (2认同)
  • 模式如何在`$ {COMMAND // [$'\ t\r \n']}中工作?我以为`$ {COMMAND // [\ t\r \n]}`只会起作用,但事实并非如此.什么是`$`符号和单引号? (2认同)

Rob*_*een 76

echo "|$COMMAND|"|tr '\n' ' '
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 为什么你不使用`tr -d'\n'`来*删除*代替*替换空格* (29认同)
  • @ F.Hauri:或者无用的tr:'"| $ {COMMAND // $'\n'} |"` (12认同)
  • 请whipe无用的管道!使用`tr'\n'''<<<"| $ COMMAND |"`而不是`echo ... | ...` (3认同)
  • 是.但请告诉我你不允许任意人在没有密码的情况下远程重启你的服务器...... (2认同)

Max*_*amy 67

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

COMMAND=$(echo $COMMAND|tr -d '\n')
Run Code Online (Sandbox Code Playgroud)

  • 这不是剥线换行吗?不应该是`tr -d'\ r'`而不是? (21认同)
  • 回显未注释的变量将删除所有IFS字符(默认情况下为换行符,空格和制表符)。因此,如果要执行此操作,则应注意,所有* IFS字符均已删除,并且不需要`tr`。只是`COMMAND = $(echo $ COMMAND)`会产生类似的效果。大概是魔鬼在调用一个新的过程时产生的,但是它对于人类的眼睛来说仍然是短暂而甜蜜的,如果您有一两秒钟的余地,您可能会愿意承受这个打击。 (2认同)

Pra*_*chi 10

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

testVar 包含我的变量/脚本输出的地方


gao*_*the 7

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

就我而言,我发现|awk '{print $2}'以该行最后一项的 awk 打印结尾的命令包括回车 \r 和引号。

我曾经sed 's/["\n\r]//g'去掉回车符和引号。

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

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

$ 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   |
Run Code Online (Sandbox Code Playgroud)

这是相关的: 什么是回车、换行和换页?

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


wjo*_*dan 6

使用bash:

echo "|${COMMAND/$'\n'}|"
Run Code Online (Sandbox Code Playgroud)

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

说明

使用Bash Shell参数扩展 ${parameter/pattern/string}:

的图案被膨胀,以产生一个模式,就像在文件名扩展。扩展参数,并将模式与其值的最长匹配项替换为string。[...]如果string为null,则删除模式匹配项,并且/后面的模式可以省略。

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

echo "|${COMMAND/
}|"
Run Code Online (Sandbox Code Playgroud)

完整的例子

#!/bin/bash
COMMAND="$'\n'REBOOT"
echo "|${COMMAND/$'\n'}|"
# Outputs |REBOOT|
Run Code Online (Sandbox Code Playgroud)

或者,使用换行符:

#!/bin/bash
COMMAND="
REBOOT"
echo "|${COMMAND/
}|"
# Outputs |REBOOT|
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您不想为如此简单的任务生成(tr、sed 或 awk)等进程,请使用此 bashism。Bash 可以单独做到这一点:

COMMAND=${COMMAND//$'\n'/}
Run Code Online (Sandbox Code Playgroud)

从文档中:

${FOO//from/to} Replace all
${FOO/from/to}  Replace first match
Run Code Online (Sandbox Code Playgroud)


zer*_*mpl 5

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

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

这输出:

|
RE BOOT|
Run Code Online (Sandbox Code Playgroud)

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