簡體   English   中英

如何從 Bash 中的字符串中刪除換行符

[英]How to remove a newline from a string in Bash

我有以下變量。

echo "|$COMMAND|"

返回

|
REBOOT|

如何刪除第一個換行符?

下,有一些 bashisms:

tr命令可以替換為// bashism

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確實包含空格怎么辦......

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 )以便使用*(...)語法。

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

將用空格替換換行符(在 POSIX/Unix 中它不是回車符)。

老實說,我會考慮從 bash 切換到更理智的東西。 或者首先避免生成這種格式錯誤的數據。

嗯,這似乎也可能是一個可怕的安全漏洞,具體取決於數據的來源。

通過刪除所有回車符來清理變量:

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

使用bash

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

(請注意,此問題中的控制字符是“換行符”( \n ),而不是回車符( \r );后者將在一行上輸出REBOOT| 。)

解釋

使用 Bash Shell 參數擴展${parameter/pattern/string}

模式被擴展以產生一個模式,就像在文件名擴展中一樣。 參數被擴展,模式與其值的最長匹配被替換為字符串 [...] 如果string為 null,則刪除模式匹配項,並且可以省略/后面的模式

還使用$'' ANSI-C 引用結構將換行符指定為$'\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 包含我的變量/腳本輸出

添加答案以顯示剝離多個字符的示例,包括使用 tr 和使用 sed 的 \r。 並說明使用 hexdump。

就我而言,我發現以 awk print 結尾的命令最后一項|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   |

這很重要: 什么是回車、換行和換頁?

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

如果您在啟用 extglob 選項的情況下使用 bash,則可以通過以下方式僅刪除尾隨空格:

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

這輸出:

|
RE BOOT|

或者將 %% 替換為 ## 以僅替換前導空格。

您可以簡單地使用echo -n "|$COMMAND|" .

$ man echo

-n不輸出尾隨換行符

為了解決實際問題的一個可能根源,您可能正在采購一個 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

簡短的答案是最好的(請upwote)如果您不希望像(tr,sed或awk)這樣的簡單任務產生過程,請使用此bashism,bash可以單獨完成:

COMMAND=${COMMAND//$'\n'/}

從文檔:

${FOO//from/to} Replace all
${FOO/from/to}  Replace first match

感謝您的支持。 這是最好的答案。

Grep 可用於過濾掉任何空行。 如果您有幾行數據並且想要刪除任何空白,這將很有用。

echo "$COMMAND" | grep .

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM