はじめに
ディレクトリ同士をdiff
コマンドで再帰的に比較するときは、
diff -r <dir1> <dir2>
みたいにしますよね。
その中で特定ファイル名の結果を除外したい場合は
diff -r -x <filename> <dir1> <dir2>
みたいにすればOK。
参考: https://linuxjm.osdn.jp/html/gnumaniak/man1/diff.1.html
しかし!除外はできるくせに「特定ファイル名の結果だけを表示」ってのは
diff
コマンドの機能としては存在しないようです。
-q
オプション付きであれば、diff -qr <dir1> <dir2> | grep <filename>
でOKだけど、
ファイルの中身までちゃんと見たいときはそうは行かない。
やりたくなる度に調べては「やっぱないよなー。。。」ってガッカリしてたんですが、
無いならシェルスクリプト組んでやれ!と思って作りました。
コード
実行権限を付けて保存して、こんな風に実行してみてください〜。
./tdiff.sh <dir1> <dir2> <target filename>
#!/usr/bin/env bash
# diffコマンド名(普通のdiffでもOK)
# diffCommand=diff
diffCommand=colordiff
# 第一引数がハイフンで始まったらそのままdiffのオプションに渡す
if [ "${1:0:1}" = "-" ]; then
option="$1"
shift
else
option="-uN"
fi
if [ $# -lt 3 ]; then
echo "Usage: $0 [<diff option>] <dir1> <dir2> <target filename>"
exit 1
fi
# $1 $2はディレクトリ名、$3はdiffを取りたいファイル名
output=$(diff -qr $1 $2)
while read -r line; do
string=$(echo "$line" | awk '{print $1}');
if [ $(echo $string | grep -e 'Only') ]; then
# 片方にしかファイルがない場合
fileName=$(echo "$line" | awk '{print $4}');
if [ $fileName != "$3" ]; then
continue
fi
path=$(echo "$line" | awk '{print $3}' | sed -e "s/\:/\//");
fromFile=${path/$1/$2/}/$fileName;
toFile=${path/$2/$1/}/$fileName;
else
# 両方にファイルがある場合
fromFile=$(echo "$line" | awk '{print $2}');
toFile=$(echo "$line" | awk '{print $4}');
fileName=$(basename "$toFile")
if [ $fileName != "$3" ]; then
continue
fi
fi
$diffCommand $option $fromFile $toFile
done <<< "$output"
補足
僕は色付きが好きなのでcolordiffを指定してますが、
インストールされてなければエラーになるはずなので注意してください。
alias tdiff=~/hoge/fuga/tdiff.sh
みたいにエイリアス貼ると便利です。
スクリプト名tdiff
は「targetable diff」って意味です。
謝辞
全部自力で書くのは時間かかりそうなので
似たようなことやってる人探したところ、
ディレクトリ間の差分ファイル一覧取得をbash scriptで実現させる
がとても参考になりました!
かなり流用させてもらいまして感謝感謝
おわりに
実はシェル芸も大好きなので、もっと腕磨いてQiitaにもどんどん書きたいなーと思った所存です。
ではまた〜。