
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 zsh
script de shell que usa o comando integrado zstat
para obter portável os tamanhos dos arquivos.
O script percorrerá todos os arquivos regulares com nomes não ocultos no dir2
diretório. Para cada arquivo nele dir2
será construído o nome do caminho correspondente para um arquivo em dir1
. Se o arquivo dir1
existir e for um arquivo normal (ou um link simbólico para um arquivo normal), o tamanho dos dois arquivos será comparado. Se o arquivo dir2
for estritamente maior, uma mensagem curta será exibida.
O padrão dir2/*(.)
corresponderá apenas a nomes não ocultos de arquivos regulares no dir2
diretório. O (.)
é um zsh
modificador 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 $file2
com 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 dir2
tenham os mesmos nomes dos arquivos em dir1
, conforme descrito acima.
realpath
imprime o caminho absoluto do arquivo.
Este script também compara arquivos ocultos (arquivos que começam com .
).