Compare os arquivos e selecione um maior

Compare os arquivos e selecione um maior

Existem dois diretórios com muitos arquivos. Esses arquivos sempre correspondem em nomes e nem sempre em tamanho. Por exemplo:

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

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

Como você pode ver, os nomes dos arquivos correspondem, mas o tamanho do arquivo corresponde apenas ao arquivo2. Como posso comparar arquivos nesses 2 diretórios e selecionar apenas os arquivos maiores? A saída no caso de exemplo deve ser "/dir2/file3".

Se houver um arquivo em dir1 maior que o arquivo com o mesmo nome em dir2 = então não faça nada. Estou interessado apenas em arquivos no dir2 que sejam maiores que os do dir1

Eu escrevi um script, mas ele só funciona se um arquivo maior no dir2 for encontrado.

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

Responder1

#!/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 é um zshscript de shell que usa o comando integrado zstatpara obter portável os tamanhos dos arquivos.

O script percorrerá todos os arquivos regulares com nomes não ocultos no dir2diretório. Para cada arquivo nele dir2será construído o nome do caminho correspondente para um arquivo em dir1. Se o arquivo dir1existir e for um arquivo normal (ou um link simbólico para um arquivo normal), o tamanho dos dois arquivos será comparado. Se o arquivo dir2for estritamente maior, uma mensagem curta será exibida.

O padrão dir2/*(.)corresponderá apenas a nomes não ocultos de arquivos regulares no dir2diretório. O (.)é um zshmodificador específico *que faz com que ele corresponda apenas a arquivos regulares.

A expressão "dir1/${file2##*/}"se expandirá para um nome de caminho começando dir1/e contendo o valor de $file2com tudo antes e incluindo o último /removido. Isso pode ser alterado para "dir1/$( basename "$file2" )".

Responder2

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

Isso pressupõe que todos os arquivos dir2tenham os mesmos nomes dos arquivos em dir1, conforme descrito acima.

realpathimprime o caminho absoluto do arquivo.

Este script também compara arquivos ocultos (arquivos que começam com .).

informação relacionada