70812

[code]

     #!/bin/bash
      fuga=" string"
      
      
      echo ${fuga} | sed -e 's|^\s||'
    
[/code]

出力

[code]

    tring
    
[/code]

これはどんな使用ですか？環境依存でしょうか？


CC BY-SA 4.0
2020-09-29T10:00:40.767
70809
2020-09-29T13:38:32.730
2020-09-29T13:38:32.730
3061
31135
question
bash 正規表現 sed
bashの先頭半角置換の正しい書き方


# シェルの挙動

シェルは与えられたコマンドライン文字列に対して変数展開 (variable expansion)、ワード分割 (word splitting)、パス名展開
(pathname expasion) などを実行し、その結果をコマンドとして実行します。

`echo ${fuga}` がどのように解釈されるかというと:

  1. 変数展開が実行され `echo string` と解釈される  
(`echo` と `string` の間に ` ` (スペース 2 つ))

  2. ワード分割により空白文字 (1 文字以上のスペースやタブなど) で分割され `echo` と `string` の 2 要素として解釈される。
  3. `echo` コマンドにコマンドライン引数 1 つ `string` を指定して実行する。
  4. `echo` コマンドの実行により `string` が出力される。

このようにワード分割の過程で `${fuga}` の先頭にあったスペースが失われたものが `echo` に渡され、結果 `sed` には `string`
だけが渡されます。

コマンドライン中のスペースなどをワード分割の対象外にするには `\` (バックスラッシュ) でエスケープしたり `"` (ダブルクォート) か `'`
(シングルクォート)
で括ってエスケープする必要があります。変数に含まれるスペースなどのワード分割を防ぐにはダブルクォートで括って変数展開する必要があります。

# sed の違いによる正規表現の違い

`sed` が対応する正規表現は「BRE」(basic regular expressions、基本正規表現) であって「ERE」(extended
regular expressions、拡張正規表現) ではありません。よって正規表現 `\s` はBRE としては `s` と等価であり、これは `s`
にだけマッチします。

しかし GNU sed などの特殊な sed は BRE ではなく ERE 的な BRE として解釈する機能が実装されており、正規表現 `\s`
は「空白文字」にマッチします。(GNU sed は `--regexp-extended` オプションを指定することにより ERE
が利用できるのに、何故こんな余計な機能を設けたのかは理解に苦しむところ)

よって sed の実装に依存しない (移植性 (portability) を考慮した) sed スクリプトを書くには GNU sed
などの特殊な実装を考慮した BRE を記述する必要があります。

# 結局どうすればいいの?

「`${fuga}` に含まれるスペースなどを維持する」、「sed で先頭の 1 文字以上のスペースを削除する」(移植性を考慮する)
でよければ、スクリプトは次のようになります。

[code]

    #!/bin/bash
    fuga=" string"
      
    echo "${fuga}" | sed -e 's|^ *||'
    
[/code]


CC BY-SA 4.0
2020-09-29T11:51:57.603
70812
2020-09-29T13:36:31.443
2020-09-29T13:36:31.443
3061
3061
70809
answer