sedで特殊な記号を置換・削除


ディレクトリを変更したのでファイル内の環境変数もすべて変更したい。

test.sh
../../${dir}/file1.txt
../../${dir}/file2.txt
../../${dir}/file3.txt
../../${dir}/file4.txt
../../${dir}/file5.txt

test.sh
../file1.txt
../file2.txt
../file3.txt
../file4.txt
../file5.txt

こうしたい

つまり
../${dir}/
の部分を削除したい時。

成功したものが以下のコマンド


sed -i s@'../${dir}/'@@g test.sh



解説

検索するとよく出てくるsedの構文は以下の通り
(これがあとあと苦労する原因)

sed 's/置換したい文字列/置換後の文字列/g' 入力ファイル名

gは入力ファイル中の文字列すべてを置換という意味。


オプションを追加

sed -i 's/置換したい文字列/置換後の文字列/g' 入力ファイル名

-iオプションを使うことでパイプ&catをしなくてもファイルを上書きできる。

今回は何度も失敗したので-iオプションの後に".org"を追加。

sed -i".org" 's/置換したい文字列/置換後の文字列/g' 入力ファイル名

これでtest.sh.orgが作成され、バックアップが取れる。


さて、本題の特殊記号の置換だ。
とりあえず以下を実行してみた。

sed -i".org" 's/../${dir}///g' test.sh

sed: -e expression #1, char 13: unknown option to `s'

エラーが出る。
スラッシュが問題のようだ。

ならば置換したい文字列を''で囲ってみる。

sed -i".org" 's/'../${dir}/'//g' test.sh

sed: -e expression #1, char 7: unknown option to `s'

調べてみると、文字列中に「/(スラッシュ)」がある場合は
sedのスラッシュを違う記号に変えるとよいらしい。
今回は「@」を使用したが、「:」や「*」、「#」など、
文字列中に使用していない記号なら何でもよいらしい。

sed -i".org" 's@'../${dir}/'@@g' test.sh



エラーが出てこなかったのでviで確認すると

test.sh
${difile1.txt
${difile2.txt
${difile3.txt
${difile4.txt
${difile5.txt

なんじゃこりゃ・・・

test.sh.org
../../${dir}/file1.txt
../../${dir}/file2.txt
../../${dir}/file3.txt
../../${dir}/file4.txt
../../${dir}/file5.txt

バックアップを取っておいてよかった。

mv test.sh.org test.sh


色々試すも、全部だめ

sed -i".org" "s@'../${dir}/'@@g" test.sh
sed -i".org" "s@../${dir}/@@g" test.sh

試行錯誤したが、どうやらsedコマンド自体のスラッシュがいらない模様。

sed -i".org" s@../${dir}/@@g test.sh

文字列はちゃんと囲めってことか


sed -i".org" s@'../${dir}/'@@g test.sh

成功しました。


クォーテーションの意味をちゃんと考えなくてはと思った一件でした。