web-dev-qa-db-ja.com

Bashの文字列から改行を削除する方法

次の変数があります。

echo "|$COMMAND|"

返す

|
REBOOT|

最初の改行を削除するにはどうすればよいですか?

90
Matt Leyland

bash の下には、いくつかのバシズムがあります:

trコマンドは、//bashismに置き換えることができます。

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

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

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

BashのmanページのParameter Expansionおよび引用符を参照してください。

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

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

さらに...

@AlexJordanが尋ねたように、これはall指定された文字を抑制します。では、$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|

注: bash には、*(...)構文を使用するために有効にするextglobオプションがあります(shopt -s extglob)。

93
F. Hauri
echo "|$COMMAND|"|tr '\n' ' '

改行(POSIX/Unixではキャリッジリターンではありません)をスペースに置き換えます。

正直に言うと、bashからもっと健全なものに切り替えることを考えています。または、そもそもこの不正なデータを生成しないようにします。

うーん、これはデータの送信元によっては恐ろしいセキュリティホールにもなりそうです。

72
Robin Green

すべてのキャリッジリターンを削除して変数を消去します。

COMMAND=$(echo $COMMAND|tr -d '\n')
57
Maxime Chéramy

bashの使用:

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

(この質問の制御文字はキャリッジリターン(\n)ではなく、「改行」(\r)です。後者は単一行にREBOOT|を出力します。)

説明

Bashを使用します シェルパラメーター展開${parameter/pattern/string}

patternは、ファイル名の展開と同様にパターンを生成するために展開されます。 Parameterが展開され、その値に対するpatternの最長一致が置き換えられますwithstring [...]stringがnullの場合、patternの一致はnull削除され、/に続く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|
5
wjordan

単にecho -n "|$COMMAND|"を使用できます。

2
Paulo

Extglobオプションを有効にしてbashを使用している場合は、次の方法で末尾の空白のみを削除できます。

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

この出力:

|
RE BOOT|

または、%%を##で置き換えて、先頭の空白のみを置き換えます。

2
zeroimpl

Trとsedを使用して\ rを含む複数の文字を削除する例を示す回答を追加します。そして、hexdumpを使用して説明します。

私の場合、行の最後の項目|awk '{print $2}'のawk印刷で終わるコマンドには、キャリッジリターン\ 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
2
gaoithe

私のために働いたのはecho $testVar | tr "\n" " "でした

TestVarに変数/スクリプト出力が含まれていた場所

1
Prachi