Compara archivos y selecciona uno más grande

Compara archivos y selecciona uno más grande

Hay dos directorios con muchos archivos. Esos archivos siempre coinciden en nombres y no siempre coinciden en tamaño. Por ejemplo:

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

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

Como puede ver, los nombres de archivos coinciden pero el tamaño de archivo solo coincide en el archivo2. ¿Cómo puedo comparar archivos en esos 2 directorios y seleccionar solo los archivos que son más grandes? La salida en el caso de ejemplo debe ser "/dir2/file3".

Si hay un archivo en dir1 que es más grande que el archivo con el mismo nombre en dir2 = entonces no hagas nada. Solo me interesan los archivos en dir2 que son más grandes que los de dir1

Escribí un script, pero solo funciona si se encuentra un archivo más grande en dir2.

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

Respuesta1

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

Este es un zshscript de shell que utiliza el comando integrado zstatpara obtener los tamaños de archivo de forma portátil.

El script recorrerá todos los archivos normales con nombres no ocultos en el dir2directorio. Para cada archivo que contiene, dir2se construirá el nombre de ruta correspondiente para un archivo en formato dir1. Si el archivo dir1existe y es un archivo normal (o un enlace simbólico a un archivo normal), se compara el tamaño de los dos archivos. Si el archivo dir2es estrictamente más grande, se genera un mensaje corto.

El patrón dir2/*(.)coincidirá sólo con nombres no ocultos de archivos normales en el dir2directorio. Es (.)un zshmodificador específico *que hace que coincida solo con archivos normales.

La expresión "dir1/${file2##*/}"se expandirá a un nombre de ruta que comienza con dir1/y luego contiene el valor de $file2con todo lo anterior e incluido el último /eliminado. Esto podría cambiarse a "dir1/$( basename "$file2" )".

Respuesta2

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

Esto supone que todos los archivos dir2tienen los mismos nombres que los archivos en dir1, como se describe anteriormente.

realpathimprime la ruta absoluta del archivo.

Este script también compara archivos ocultos (archivos que comienzan con .).

información relacionada