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


110

次の変数があります。

echo "|$COMMAND|"

戻る

|
REBOOT|

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


7
なぜこれはだまされているとマークされているのですか?この質問は、キャリッジリターンの削除についてです。リンクされている疑わしい重複した質問は、空白を削除することに関するものであり、偶然に改行に言及しているだけです。
Michael Scheper 2014年

1
@MichaelScheperが同意し、再開しました。
fedorqui 'SO stop harming'

ここの用語は奇妙です。Unixの行終端文字\n(16進数の0x0A)は、改行(LF)と呼ばれます。これは\r、Windowsおよび多くのネットワークプロトコルで2バイトの行末シーケンスCR LFの最初のバイトとして使用される文字キャリッジリターン(CR)(hex 0x0D)とは異なります。
Tripleee、2018年

回答:


114

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

trコマンドを置き換えることができ// bashism

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

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

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

参照パラメータ展開をしてQUOTINGのbashのmanページに:

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使用するために)*(...)構文を。


1
これは、BASHの変数から改行を取り除く方法です。他の答えは不必要に余分なTRプロセスを呼び出すことです。ところで、それは終了スペースを削除するという追加の利点があります!
ingyhere 2015年

1
文字列から内部スペースも削除されることに注意してください... COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n ']}|"戻り値|REBOOT|
Alex Jordan

2
@AlexJordanはい、それはですたかっ機能:後は、スペースをwhipeことができ\n、これを防ぐために:COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n']}|"戻ります|RE BOOT|
F.ハウリ2016年

2
パターンはどのように機能し${COMMAND//[$'\t\r\n']}ますか?私${COMMAND//[\t\r\n]}は単純にうまくいくと思っていましたが、うまくいきませんでした。何である$ため、あまりにも単一引用符記号は?
haridsv

1
$ ''構文に関しては、ANSI Cの引用です(wjordansの回答で述べられています)。
chuckx

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

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

正直なところ、bashからより健全なものに切り替えることを考えます。または、最初にこの不正なデータの生成を回避します。

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


日付は同じサーバー上にあるカールリクエストから来ています。それを新しい変数に入れるにはどうすればよいですか?newvar = $(echo "| $ COMMAND |" | tr '\ n' '')
Matt Leyland

2
はい。しかし、パスワードなしで任意の人がサーバーをリモートで再起動することを許可していないことを教えてください...
Robin Green

31
スペース置き換えるのではなくドロップに使用tr -d '\n'しなかった理由
F. Hauri

3
役に立たないパイプを泡立ててください!使用tr '\n' ' ' <<< "|$COMMAND|"の代わりにecho ... | ...
F. HAURI

12
@ F.Hauri:または役に立たないtr:"|${COMMAND//$'\n'}|"
rici

75

すべての改行を削除して変数をクリーンアップします。

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

22
それはラインフィードを取り除きませんか?tr -d '\r'代わりにすべきではありませんか?
Izzy、2014年

3
コメント化されていない変数をエコーすると、すべてのIFS文字(デフォルトでは改行、スペース、タブ)が削除されます。したがって、これを行う場合は、すべての IFS文字が削除され、は必要ないことに注意してくださいtr。単純COMMAND=$(echo $COMMAND)に同様の効果が得られます。これはおそらく新しいプロセスを呼び出すための悪魔のスポーンですが、それでも人間の目にはかなり短くて甘いです。あなたの人生で2〜2秒の余裕があれば、ヒットを喜んで受け入れるかもしれません:-)。
Mike S

この例では、改行ではなく改行であることが示されているため、質問を「改行」に変更しました。この答えはまだ正しいですが、「改行」ではなく「改行」となるように更新する必要がありますか?
ベンジャミンW.

8

使用bash

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

(この質問の制御文字は「改行」(\n)であり、復帰(\r)ではないことに注意してください。後者はREBOOT|単一行に出力されます。)

説明

Bash Shell Parameter Expansionを 使用し${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|

6

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

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


4

trを使用した\ rとsedを使用した\ rを含む複数の文字を取り除く例を示すための回答を追加します。そして、hexdumpを使用して説明します。

私の場合|awk '{print $2}'、行の最後の項目のawk printで終わるコマンドに、キャリッジリターン\ rと引用符が含まれていることがわかりました。

以前sed 's/["\n\r]//g'は、キャリッジリターンとクオートの両方を取り除いていました。

私も使用できたでしょうtr -d '"\r\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

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

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

これは出力します:

|
RE BOOT|

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


1
これは、私がdockerコマンドから取得した奇妙な出力を持つ魅力のように機能しました。どうもありがとう!
develCuy 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.