LoginSignup
0
3

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-01-27
動作環境
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

処理結果

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

qiita.png

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

TODO リスト

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