ファイルを比較して大きい方を選択する

ファイルを比較して大きい方を選択する

多数のファイルを含む 2 つのディレクトリがあります。これらのファイルの名前は常に一致しますが、サイズは必ずしも一致しません。例:

/dir1
|-file1 (1 MB)
|-file2 (2 MB)
|-file3 (3 MB)

/dir2
|-file1 (1 KB)
|-file2 (2 MB)
|-file3 (10 MB)

ご覧のとおり、ファイル名は一致していますが、ファイルサイズは file2 でのみ一致しています。これら 2 つのディレクトリ内のファイルを比較し、大きい方のファイルのみを選択するにはどうすればよいでしょうか。この例の出力は「/dir2/file3」である必要があります。

dir1 に dir2 の同じ名前のファイルよりも大きいファイルがある場合 = 何もしません。私が関心があるのは、dir2 のファイルが dir1 のファイルよりも大きいかどうかだけです。

スクリプトを作成しましたが、dir2 内に 1 つの大きなファイルが見つかった場合にのみ機能します。

#!/bin/bash
diff -q $1 $2 | awk '{ print $2,$4 }' > tempfile.txt
A=`cat tempfile.txt | cut -d ' ' -f 1`
B=`ls -s $A | cut -d ' ' -f 1`
C=`cat tempfile.txt | cut -d ' ' -f 2`
D=`ls -s $C | cut -d ' ' -f 1`
if [ "$D" -gt "$B" ]; then
 echo $C
fi

答え1

#!/usr/bin/env zsh

zmodload -F zsh/stat b:zstat

for file2 in dir2/*(.); do
    file1="dir1/${file2##*/}"

    if [ -f "$file1" ] &&
       [ "$( zstat +size "$file2" )" -gt "$( zstat +size "$file1" )" ]
    then
        printf '%s is bigger than %s\n' "$file2" "$file1"
    fi
done

zshこれは、組み込みコマンドを使用してzstatファイル サイズを移植可能に取得するシェル スクリプトです。

スクリプトは、dir2ディレクトリ内の隠し名前のないすべての通常ファイルをループします。 内の各ファイルに対して、dir2内のファイルに対応するパス名を構築しますdir1。 内のファイルがdir1存在し、通常ファイル (または通常ファイルへのシンボリック リンク) である場合、2 つのファイルのサイズが比較されます。 内のファイルの方が確実に大きい場合はdir2、短いメッセージが出力されます。

パターンは、ディレクトリdir2/*(.)内の通常のファイルの非隠し名前にのみ一致しますdir2。 は、通常のファイルのみに一致させるの -specific 修飾子(.)です。zsh*

式は、 で始まり、 の値を含み、最後の を含むすべてのものが削除された"dir1/${file2##*/}"パス名に展開されます。これは に変更できます。dir1/$file2/"dir1/$( basename "$file2" )"

答え2

#!/bin/bash

get_attr() {
    # pass '%f' to $2 to get file name(s) or '%s' to get file size(s)
    find "$1" -maxdepth 1 -type f -printf "$2\n"
}

while read -r file
do
    (( $(get_attr "dir2/$file" '%s') > $(get_attr "dir1/$file" '%s') )) \
        && realpath -e "dir2/$file"
done < <(get_attr dir2 '%f')

これは、上で説明したように、内のすべてのファイルがdir2内のファイルと同じ名前を持つことを前提としています。dir1

realpathファイルの絶対パスを出力します。

このスクリプトは、隠しファイル ( で始まるファイル.) も比較します。

関連情報