次の変数があります。
echo "|$COMMAND|"
戻る
|
REBOOT|
最初の改行を削除するにはどうすればよいですか?
\n
(16進数の0x0A)は、改行(LF)と呼ばれます。これは\r
、Windowsおよび多くのネットワークプロトコルで2バイトの行末シーケンスCR LFの最初のバイトとして使用される文字キャリッジリターン(CR)(hex 0x0D)とは異なります。
次の変数があります。
echo "|$COMMAND|"
戻る
|
REBOOT|
最初の改行を削除するにはどうすればよいですか?
\n
(16進数の0x0A)は、改行(LF)と呼ばれます。これは\r
、Windowsおよび多くのネットワークプロトコルで2バイトの行末シーケンスCR LFの最初のバイトとして使用される文字キャリッジリターン(CR)(hex 0x0D)とは異なります。
回答:
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
使用するために)*(...)
構文を。
COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n ']}|"
戻り値|REBOOT|
\n
、これを防ぐために:COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n']}|"
戻ります|RE BOOT|
。
${COMMAND//[$'\t\r\n']}
ますか?私${COMMAND//[\t\r\n]}
は単純にうまくいくと思っていましたが、うまくいきませんでした。何である$
ため、あまりにも単一引用符記号は?
echo "|$COMMAND|"|tr '\n' ' '
改行(POSIX / Unixではキャリッジリターンではありません)をスペースに置き換えます。
正直なところ、bashからより健全なものに切り替えることを考えます。または、最初にこの不正なデータの生成を回避します。
うーん、これは、データの送信元によっては、恐ろしいセキュリティホールになる可能性もあるようです。
tr -d '\n'
しなかった理由
tr '\n' ' ' <<< "|$COMMAND|"
の代わりにecho ... | ...
"|${COMMAND//$'\n'}|"
すべての改行を削除して変数をクリーンアップします。
COMMAND=$(echo $COMMAND|tr -d '\n')
tr -d '\r'
代わりにすべきではありませんか?
tr
。単純COMMAND=$(echo $COMMAND)
に同様の効果が得られます。これはおそらく新しいプロセスを呼び出すための悪魔のスポーンですが、それでも人間の目にはかなり短くて甘いです。あなたの人生で2〜2秒の余裕があれば、ヒットを喜んで受け入れるかもしれません:-)。
使用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|
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 |
これは重要です。 キャリッジリターン、ラインフィード、フォームフィードとは何ですか。
extglobオプションを有効にしてbashを使用している場合は、次のようにして末尾の空白のみを削除できます。
shopt -s extglob
COMMAND=$'\nRE BOOT\r \n'
echo "|${COMMAND%%*([$'\t\r\n '])}|"
これは出力します:
|
RE BOOT|
または、%%を##で置き換えて、先頭の空白のみを置き換えます。