LoginSignup
12

More than 5 years have passed since last update.

sedでドライランする

Posted at

sedにドライランオプションはないけど、ファイルを変更せずにdiffが見たい。

sed command in dry run - Stack Overflowにコマンドを組み合わせて、diffを見るやり方が書いてあった。

例えば

editor.txt
Vim
Emacs
Atom
Visual Studio Code

こんなファイルがあった場合に

$ sed 's/Emacs/Vim/g' editor.txt | diff editor.txt -
--- editor.txt  2017-05-07 12:47:25.000000000 +0900
+++ -   2017-05-07 12:47:59.390599000 +0900
@@ -1,4 +1,4 @@
 Vim
-Emacs
+Vim
 Atom
 Visual Studio Code

な感じでdiffが見れる。

これをシェルスクリプト化してみた。

sedd
#!/usr/bin/env bash
progname=$(basename $0)

usage() {
  cat <<EOT
Usage: $progname [OPTIONS]

Options:
  -h, --help
  -n, --dry-run
EOT
}

for OPT in "$@"
do
  case "$OPT" in
    '-h'|'--help' )
      usage
      ;;
    '-n'|'--dry-run' )
      dryrun=1
      shift 1
      ;;
    *)
      param+=( $(printf %q "$1") )
      shift 1
      ;;
  esac
done

if [ -z "$param" ]; then
  usage
  exit 1
fi

if [ "$dryrun" ]; then
  cmd="sed ${param[@]} {} | diff -u {} -"
  exec find . -type f -exec sh -c "$cmd" \;
fi

eval "find . -type f -exec sed -i ${param[@]} {} +"

-n--dry-runをつけるとドライラン

$ sedd 's/Emacs/Vim/' -n
--- ./editor.txt        2017-05-07 12:47:25.000000000 +0900
+++ -   2017-05-07 12:55:16.585676000 +0900
@@ -1,4 +1,4 @@
 Vim
-Emacs
+Vim
 Atom
 Visual Studio Code

つけないと実行される。-eで複数指定してもうまくいく。

$ sedd -e 's/Emacs/Vim/' -e 's/Atom/Vim/' -n
--- ./editor.txt        2017-05-07 12:47:25.000000000 +0900
+++ -   2017-05-07 13:10:30.560533000 +0900
@@ -1,4 +1,4 @@
 Vim
-Emacs
-Atom
+Vim
+Vim
 Visual Studio Code

対象はカレントワーキングディレクトリ以下のファイル全体にしている。

オプション解析のところで、param+=( $(printf %q "$1") )しているのは

$ sedd 's/Visual Studio Code/Vim/' -n

のように引数に空白などのエスケープが必要な文字が来ても、後のsed実行時に問題なく動かすため。

$ printf %q 's/Visual Studio Code/Vim'
s/Visual\ Studio\ Code/Vim

な感じに変換される。printf %qについてはBashで文字列をエスケープをする - Qiitaで知った。

最後のfindの+は、-execで対象ファイルを並べるオプション

sed -i ${param[@]} file1 file2 ...

みたいな感じになり、1個ずつファイルをsedするよりも早くなる。

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
12