bash script > 2つのディレクトリにある同じ名前のファイルを探す > (文字列置換 / diffで探す方法) > RANDOMで処理する/しない > diffでは同じ名前で内容が異なるファイルは見つからない


動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

以下を行いたい

  1. 2つのディレクトリにある同じ名前のファイルを比較
  2. ランダムに取り出す
  3. ファイル(png画像)を比較したhtmlファイルを生成 (タイトル付き)
  4. pdf化

目的は、WRF(Weather Research and Forecasting Model)で処理した結果画像の比較。

v0.1 > 文字列置換 + if [ -e

2つのディレクトリに同じ名前のファイルがあるかチェックするbash scriptを実装してみた。

参考(文字列置換) http://d.hatena.ne.jp/ozuma/20130928/1380380390

code

compare_images_170127_exec
#!/usr/bin/env bash

#
# v0.1 Jan,27,2017
#   - find files in both directories
#

if [ $# -lt 2 ]; then
    echo "Usage:"
    echo "  [cmd] [source1 dir] [source2 dir]"
    echo "  to compare files with same names in 2 dirs"
    echo 
    exit
fi

src1dir=$1
src2dir=$2

#echo $src1dir
#echo $src2dir

for src1file in $(ls $src1dir/*.png);do
    # echo $src1file
    src2file=${src1file/$src1dir/$src2dir}

    if [ -e $src2file ]; then
        echo $src2file
    fi

    #break; // for debug
done

テストデータ生成

mkdir WORK_A
mkdir WORK_B
touch WORK_A/AAA.png
touch WORK_A/BBB.png
touch WORK_A/CCC.png
touch WORK_A/DDD.png
touch WORK_B/BBB.png
touch WORK_B/DDD.png

これでBBB.pngとDDD.pngのみ共通となる。

実行例 > 引数なし (使い方の表示)

$ bash compare_images_170127_exec 
Usage:
  [cmd] [source1 dir] [source2 dir]
  to compare files with same names in 2 dirs

実行例 > 引数あり (ファイル名表示)

$ bash compare_images_170127_exec WORK_A WORK_B
WORK_B/BBB.png
WORK_B/DDD.png

もっと簡単な方法

あれば知りたい。

あった。
http://stackoverflow.com/questions/10087571/given-two-directory-trees-how-to-find-which-files-are-the-same

$ diff -srq WORK_A WORK_B
Only in WORK_A: AAA.png
Files WORK_A/BBB.png and WORK_B/BBB.png are identical
Only in WORK_A: CCC.png
Files WORK_A/DDD.png and WORK_B/DDD.png are identical
$ diff -srq WORK_A/ WORK_B/ | grep identical
Files WORK_A/BBB.png and WORK_B/BBB.png are identical
Files WORK_A/DDD.png and WORK_B/DDD.png are identical

v0.2 > diff -srq

diff -srq使用

code

compare_images_170127_exec
#!/usr/bin/env bash

# v0.2 Jan,27,2017
#   - use [diff -srq] 
# v0.1 Jan,27,2017
#   - find files in both directories
#

if [ $# -lt 2 ]; then
    echo "Usage:"
    echo "  [cmd] [source1 dir] [source2 dir]"
    echo "  to compare files with same names in 2 dirs"
    echo 
    exit
fi

src1dir=$1
src2dir=$2

res=$(diff -srq $src1dir $src2dir | grep identical | awk '{print $2}')
for afile in $res;do
    echo $afile
done

上記、20行目のprint $2により、src1dir側のファイル名を取得する。
(Note: コードの20行目、というのはQ Acceleratorを使うと、すぐに見れます)。

結果
$ bash compare_images_170127_exec WORK_A WORK_B
WORK_A/BBB.png
WORK_A/DDD.png

v0.3 > 処理する/しないを選択 > RANDOM使用

code

compare_images_170127_exec
#!/usr/bin/env bash

# v0.3 Jan,27,2017
#   - add condition using $RANDOM to process or not
# v0.2 Jan,27,2017
#   - use [diff -srq] 
# v0.1 Jan,27,2017
#   - find files in both directories
#

if [ $# -lt 2 ]; then
    echo "Usage:"
    echo "  [cmd] [source1 dir] [source2 dir]"
    echo "  to compare files with same names in 2 dirs"
    echo 
    exit
fi

src1dir=$1
src2dir=$2

THRESHOLD=16384 # should be <= [32767]
# set smaller to increase the probability
# set larger to decrease the probability

res=$(diff -srq $src1dir $src2dir | grep identical | awk '{print $2}')
for afile in $res;do
    if  [ $RANDOM -lt $THRESHOLD ]; then
        continue
    fi
    echo $afile
done
実行
$ bash compare_images_170127_exec WORK_A WORK_B
$ bash compare_images_170127_exec WORK_A WORK_B
WORK_A/DDD.png
$ bash compare_images_170127_exec WORK_A WORK_B
WORK_A/BBB.png

diffではだめ > 同一のファイルのみ検索で見つかる

同じファイル名で、作成日時が異なる(さらに言えば、内容も少し異なる)ファイルはdiff -srqでは見つからないと気づいた。

v0.5 > diff -srqやめ / html出力

code

compare_images_170127_exec
#!/usr/bin/env bash

# v0.5 Jan,27,2017
#   - remove [diff -srq] because diff only picks up "the same file"
# v0.4 Jan,27,2017
#   - add html_output()
# v0.3 Jan,27,2017
#   - add condition using $RANDOM to process or not
# v0.2 Jan,27,2017
#   - use [diff -srq] 
# v0.1 Jan,27,2017
#   - find files in both directories
#

html_output() {
    in1file=$1
    in2file=$2
    echo "$in1file<br>"
    echo -n "<table>"
    echo -n "<tr>"
    echo -n "<td>"
    echo -n "<img src=$in1file width=300></img>"
    echo -n "</td>"
    echo -n "<td>"
    echo -n "<img src=$in2file width=300></img>"
    echo -n "</td>"
    echo -n "</tr>"
    echo -n "</table>"
    echo 
}

if [ $# -lt 2 ]; then
    echo "Usage:"
    echo "  [cmd] [source1 dir] [source2 dir]"
    echo "  to compare files with same names in 2 dirs"
    echo 
    exit
fi

src1dir=$1
src2dir=$2

THRESHOLD=16384 # should be <= [32767]
# set smaller to increase the probability
# set larger to decrease the probability

for src1file in $(ls $src1dir/*.png);do
    #echo $src1file
    src2file=${src1file/$src1dir/$src2dir}

    if [ -e $src2file ]; then
        if  [ $RANDOM -lt $THRESHOLD ]; then
            continue
        fi
        #echo $src2file
        html_output $src1file $src2file
        #break; // for debug
    fi
done

処理結果

画像サイズは適宜調整する。

2つの違いは何に起因するのか。
もやもやする。

TODO リスト

  • 2つのディレクトリにある同じ名前のファイルを比較
  • ランダムに取り出す
  • ファイル(png画像)を比較したhtmlファイルを生成 (タイトル付き)
  • pdf化