【问题标题】:How to remove a newline from a string in Bash如何从 Bash 中的字符串中删除换行符
【发布时间】:2013-10-21 04:05:55
【问题描述】:

我有以下变量。

echo "|$COMMAND|"

返回

|
REBOOT|

如何删除第一个换行符?

【问题讨论】:

    标签: bash variables


    【解决方案1】:

    为了解决实际问题的一个可能根源,您可能会采购一个 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
    

    【讨论】:

    • 谢谢你,我一直在为此烦恼一段时间,想知道为什么变量替换会弄乱我的字符串。在 linux 上使用 CRLF 文件...
    【解决方案2】:

    下,有一些bashisms:

    tr 命令可以替换为// bashism

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

    请参阅 bash 手册页中的 Parameter ExpansionQUOTING

    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) 才能使用 *(...) 语法。

    【讨论】:

    • 这是从 BASH 中的变量中去除换行符的方法。其他答案是不必要地调用额外的 TR 过程。顺便说一句,它还有删除结尾空格的额外好处!
    • 请注意,它还会从字符串中删除 internal 空格...COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n ']}|" 返回|REBOOT|
    • @AlexJordan 是的,这是一个想要的功能:您可以在\n 之后鞭打空格以防止这种情况:COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n']}|" 将返回|RE BOOT|
    • ${COMMAND//[$'\t\r\n']} 中的模式如何工作?我以为${COMMAND//[\t\r\n]} 会简单地工作,但事实并非如此。 $ 符号和单引号是什么?
    • 关于 $'' 语法,即ANSI C quoting(在 wjordans 回答中提到)。
    【解决方案3】:

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

    在我的例子中,我发现行中最后一项 |awk '{print $2}' 的 awk print 结尾的命令包括回车符 \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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

          使用bash

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

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

          说明

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

          pattern 被扩展以产生一个模式,就像在文件名扩展中一样。 Parameter 被扩展并且 pattern 与其值的最长匹配被替换为 string。 [...] 如果 string 为空,则 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|
          

          【讨论】:

            【解决方案7】:

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

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

            这个输出:

            |
            RE BOOT|
            

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

            【讨论】:

            • 这就像我从 docker 命令得到的一些奇怪输出的魅力。非常感谢!
            【解决方案8】:

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

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

            【讨论】:

            • 不是去掉换行符吗?不应该是tr -d '\r'吗?
            • 回显未注释的变量会删除所有 IFS 字符(默认情况下是换行符、空格、制表符)。因此,如果您要执行此操作,您应该知道 所有 IFS 字符都将被删除,并且您不需要 tr。只需COMMAND=$(echo $COMMAND) 就会产生类似的效果。这大概是魔鬼的产生,因为它调用了一个新的过程,但对于人类的眼睛来说,它仍然非常短暂和甜蜜,如果你有一两秒钟的空闲时间,你可能愿意接受这个打击:-)。
            • 我已将问题更新为“换行”,因为它的示例确实表明它是换行,而不是回车。这个答案仍然是正确的,但也许应该更新为“换行”而不是“回车”?
            • 应该是公认的答案,结合 bash 特定的${COMMAND//[$'\t\r\n']}
            【解决方案9】:
            echo "|$COMMAND|"|tr '\n' ' '
            

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

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

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

            【讨论】:

            • 日期来自同一服务器上的 curl 请求,我将如何将其放入新的 var 中? newvar=$(echo "|$COMMAND|"|tr '\n' ' ')
            • 是的。但请告诉我,您不允许任意人在没有密码的情况下远程重启您的服务器...
            • 你为什么不使用tr -d '\n' dropping 而不是用空格替换
            • 请鞭打无用的管道!使用tr '\n' ' ' <<< "|$COMMAND|" 而不是echo ... | ...
            • @F.Hauri: 或者没用的 tr's: "|${COMMAND//$'\n'}|"
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-01
            • 2016-04-14
            • 2011-10-13
            • 1970-01-01
            • 2016-11-30
            相关资源
            最近更新 更多