10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

sed -ie "s/ho/ge/" filename は意図通りではないかもしれない

Last updated at Posted at 2017-11-10

rm -rf
のように-つき一文字オプションはつなげて書けたりかけなかったりする。
sedはいろんな意味でややこしい。
sed -ie "s/ho/ge/" filename
は一見うまくいくが、よく見ると意図した動きにはなっていない。

意図通りのコマンド

sed -i -e "s/ho/ge/" filename

オプションをちゃんと分けて書く。

sed -ie "s/ho/ge/" filenameの動き

filenameは置換された内容で上書きされ、
置換前のバックアップがfilenameeに作成される。
filenameだけ見ていると正常に上書きされているので成功しているが、意図していないバックアップファイルが作成されている。

-ieとは何か

前述の結果から予測できるでしょうが、iの後のファイル名を付けてバックアップをとる。
-i.bakなどとされる。

-i[SUFFIX], --in-place[=SUFFIX]
ファイルをインプレース処理で編集する (SUFFIX 指定時はバックアップを取る)

[Man page of SED]

-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if SUFFIX supplied)

,

$ sed -i.bak -e 's/[11一]週間/1週間/g' dummy.txt
なんと、-iオプションに続いてバックアップファイルの接尾名を付けるだけ。

[sedだけでバックアップをとりつつ安全に上書き置換する - Qiita]

上書き前のファイルに拡張子.bakをつけて保管することもできる

sed -i.bak -e '/^#/d' config.txt


[sedでこういう時はどう書く? - Qiita]

↑記事のコメントやらリンクをたどると結構互換性とかの話が出てきたり、バックアップのミスに一瞬気づかなかったりな小さなつまづきは案外あるのかもしれない。

[sedの-iオプションの非互換 - Qiita]

[Linux(GNU)とMac(BSD)のsedの振る舞いの違いを解決 - Qiita]


## `-ie`でなぜ正規表現の置換上書きが成功するのか

`e`がオプションではなくバックアップのサフィックスになることは理解できた。
これで変なファイルが作成された謎は解決。
だが、`-e`が無いにも関わらず正規表現の置換が出来た原因が謎である。
処理を書くなら`-e`とかしこで見た。

でももうちょっとだけちゃんと解説を読むと理解できた。

>-e、--expression、-f、または --file オプションのいずれも指定されない場合、最初のオプションでない引き数が sed スクリプトとして解釈される。残りの全ての引き数は入力ファイル名として扱われる。入力ファイルが指定されない場合は、標準入力から読み込む。 

[Man page of SED]:https://linuxjm.osdn.jp/html/GNU_sed/man1/sed.1.html

つまり、`-e`はスクリプトの場所を`-e`の後ろの引数だと明示するためのものであり、スクリプトを引数で使う際に必須ではないということでした。
この例ではオプションでない**最初の**引数はスクリプトになっているので、`-e`がなくても正しくスクリプトを読み込んでいたということ。

つまり…

# <kbd>sed -ei "s/ho/ge/" filename</kbd>

sed: -e expression #1, char 1: expected \ after a', c' or `i'


`-e`のあとの`i`がスクリプトと解釈され、構文エラー?

# <kbd>sed -e -i "s/ho/ge/" filename</kbd>

sed: -e expression #1, char 1: unknown command: `-'


`-e`のあとの`-i`がスクリプトと解釈され、構文エラー?

***

正常な
<kbd>sed -i -e</kbd>
形式のありえそうな誤表記3つのうち唯一エラーが出ず、
一見意図通り動いている形式を見事に踏み抜いて悩んでいたのか…

エラーが出ずとも、対象ファイルだけではなくディレクトリ全体を確認したり、オプションはズボらずにちゃんと書きましょう?で、教訓はいいのか…?
レアケースでいいかな?

[Man page of SED]:https://linuxjm.osdn.jp/html/GNU_sed/man1/sed.1.html


[sedだけでバックアップをとりつつ安全に上書き置換する - Qiita]:https://qiita.com/nagamee/items/ec81f82bbfd59c0181be

[sedでこういう時はどう書く? - Qiita]:https://qiita.com/hirohiro77/items/7fe2f68781c41777e507

[sedの-iオプションの非互換 - Qiita]:https://qiita.com/blackenedgold/items/3231c8adec40b350cf33

[Linux(GNU)とMac(BSD)のsedの振る舞いの違いを解決 - Qiita]:https://qiita.com/narumi_888/items/e425f29b84da6b72ad62
10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?