Linuxシェルで2つのディレクトリを再帰的に比較し、両方のディレクトリで同じ場所(名前を含む)と同じ内容を持つが変更時間が異なるすべてのファイルペア(シンボリックリンクとディレクトリを含む)についてどのファイルが古いかを確認する方法?ペアの2つのファイルが同じ期間を持つ場合は、そのペアの出力があってはなりません。ペア内の2つのファイルの内容が異なり、場所が同じ場合は、そのペアの出力があってはなりません。
使用例:
# First, ensure that /tmp/d1, /tmp/d2, ~/d3, and ~/f don't exist. Then:
$ cd /tmp
$ mkdir d1 d2 ~/d3
$ touch d1/f && sleep 1 && touch d2/f ~/d3/f ~/f
$ echo "g1" > d1/g
$ echo "g2" > d2/g
$ echo "g3" > ~/d3/g
$ compare_times.sh d1 d2
d1/f is older than d2/f
$ cd d1
$ compare_times.sh . ../d2
f is older than ../d2/f
$ cd ../d2
$ compare_times.sh . ../d1
../d1/f is older than f
$ cd ..
$ compare_times.sh /tmp/d1 d2
/tmp/d1/f is older than d2/f
$ compare_times.sh d1 /tmp/d2
d1/f is older than /tmp/d2/f
$ compare_times.sh d1 ~/d3
d1/f is older than ~/d3/f
$ cd d1
$ compare_times.sh ~ .
f is older than ~/f
私たちの比較スクリプトcompare_times.sh
(もちろん、compare_times.zsh
扱いにくい変えるスプリントまたは強く打つ)は通常、ディレクトリへの絶対パスまたは相対パス(単純なパスを含む.
)である可能性がある2つの引数を受け入れる必要があります/
。
引用符のない文字列は、~
通常どおり、両方の引数でホームディレクトリとして解釈する必要があります。実際、出力からホームディレクトリを印刷するのはやや複雑かもしれません~
。
出力は通常どおり簡潔でなければなりません。たとえば path
ベストアンサー1
このスクリプトは、要件に応じて2つのディレクトリツリーを比較します。ファイル名は制限されません。 (GNUcomm
またはNULLで終わるレコードを処理できる他の同等のツールがfind
ない場合は、sort
ファイル名の改行を処理する機能を放棄する必要があります。)
#!/bin/bash
#
d1=$1 d2=$2
# Identify the set of matching file names
LC_ALL=C comm -z -12 \
<( cd -P -- "$d1" && find . -type f -print0 | LC_ALL=C sort -z ) \
<( cd -P -- "$d2" && find . -type f -print0 | LC_ALL=C sort -z ) |
while IFS= read -rd '' fn
do
# Tidy the filenames
fn=${fn#./}
f1="$d1/$fn"
f2="$d2/$fn"
# Compare content
if cmp -s -- "$f1" "$f2"
then
# Report older/newer file pairs (not those the same)
[[ "$f1" -ot "$f2" ]] && printf '%s is older than %s\n' "${f1#./}" "${f2#./}"
[[ "$f2" -ot "$f1" ]] && printf '%s is older than %s\n' "${f2#./}" "${f1#./}"
fi
done