Dateien vergleichen und größere auswählen

Dateien vergleichen und größere auswählen

Es gibt zwei Verzeichnisse mit vielen Dateien. Die Namen dieser Dateien stimmen immer überein, aber die Größe stimmt nicht immer überein. Beispiel:

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

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

Wie Sie sehen, stimmen die Dateinamen überein, aber die Dateigröße stimmt nur in Datei2 überein. Wie kann ich Dateien in diesen beiden Verzeichnissen vergleichen und nur die größeren Dateien auswählen? Die Ausgabe im Beispielfall muss „/dir2/file3“ sein.

Wenn es in dir1 eine Datei gibt, die größer ist als die gleichnamige Datei in dir2, dann nichts tun. Mich interessieren nur Dateien in dir2, die größer sind als die in dir1

Ich habe ein Skript geschrieben, aber es funktioniert nur, wenn eine größere Datei in Verzeichnis 2 gefunden wurde.

#!/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

Antwort1

#!/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

Dies ist ein zshShell-Skript, das den integrierten Befehl verwendet, zstatum die Dateigrößen portabel abzurufen.

Das Skript durchläuft alle regulären Dateien mit nicht versteckten Namen im dir2Verzeichnis. Für jede Datei in dir2wird der entsprechende Pfadname für eine Datei in erstellt dir1. Wenn die Datei in dir1existiert und eine reguläre Datei ist (oder ein symbolischer Link zu einer regulären Datei), wird die Größe der beiden Dateien verglichen. Wenn die Datei in dir2tatsächlich größer ist, wird eine kurze Meldung ausgegeben.

Das Muster dir2/*(.)stimmt nur mit nicht versteckten Namen regulärer Dateien im dir2Verzeichnis überein. Es (.)gibt einen zsh-specific-Modifikator, *der dafür sorgt, dass nur reguläre Dateien übereinstimmen.

Der Ausdruck "dir1/${file2##*/}"wird zu einem Pfadnamen erweitert, der mit beginnt dir1/und dann den Wert von enthält, $file2wobei alles davor und einschließlich des letzten /entfernt wird. Dies könnte in geändert werden "dir1/$( basename "$file2" )".

Antwort2

#!/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')

Dies setzt voraus, dass alle Dateien in dir2die gleichen Namen wie die Dateien in haben dir1, wie Sie oben beschreiben.

realpathdruckt den absoluten Pfad der Datei.

Dieses Skript vergleicht auch versteckte Dateien (Dateien, die mit einem beginnen .).

verwandte Informationen