Eu tive uma necessidade muito semelhante, então aqui está a minha solução.
Os scripts Bash podem ser um pouco complicados, especialmente quando se trata de nomes de arquivos com espaços, e se você fizer a coisa errada você pode acabar causando estragos, então é melhor dividir as coisas em pedaços gerenciáveis e testáveis.
Parte 1, um script que faz o comportamento necessário para apenas um arquivo:
#!/bin/bash
# Usage: copy_timestamp_if_identical.sh source_file dest_file
test "$#" -eq 2 || { echo "Wrong number of arguments" >&2; exit 1; }
FILE1="$1"
FILE2="$2"
test -f "$FILE1" || { echo "File \"$FILE1\" not found" >&2; exit 1; }
test -f "$FILE2" || { echo "File \"$FILE2\" not found" >&2; exit 1; }
if test "$(basename "$FILE1")" != "$(basename "$FILE2")";
then
# Not same filename
exit;
fi
if test $(md5sum "$FILE1" | cut -d ' ' -f 1) != $(md5sum "$FILE2" | cut -d ' ' -f 1);
then
# Not same contents
exit;
fi
echo "Updating \"$FILE2\" from \"$FILE1\""
touch -r "$FILE1" "$FILE2"
Parte 2:
Use 'find' para fazer a descoberta recursiva dos arquivos, o que pode ser a parte complicada.
Isso também permite condições mais avançadas, incluindo a especificação da data de modificação, para que você possa evitar tocar em coisas que definitivamente não devem ser tocadas, por segurança e velocidade. Veja -mtime
em man find
.
Por exemplo, para localizar todos os arquivos com um carimbo de data e hora da última modificação de 1 ano atrás ou mais:
find "DEST_DIRECTORY" -type f -mtime +365
em que DEST_DIRECTORY é o diretório que você deseja corrigir. Marque esta opção para retornar os arquivos que você deseja corrigir.
Parte 3:
Combine as duas partes acima. Isso é um pouco complicado, devido à necessidade de passar dois arquivos diferentes para copy_timestamp_if_identical.sh
, o que não é fácil com find
e -exec
. No final, decidi escrever um script de ajuda:
#!/bin/bash
# Usage: copy_timestamp_if_identical_helper.sh file_in_dest_dir source_dir dest_dir
test "$#" -eq 3 || { echo "Wrong number of arguments" >&2; exit 1; }
DEST_FILE="$1"
SRC_DIR="$2"
DEST_DIR="$3"
SRC_FILE="$SRC_DIR${DEST_FILE:${#DEST_DIR}}"
echo copy_timestamp_if_identical.sh "$SRC_FILE" "$DEST_FILE"
Você precisa passar os diretórios source e dest para ele, assim como o arquivo a ser modificado, assim a solução combinada se parece com:
find "DEST_DIR" -type f -mtime +365 -exec copy_timestamp_if_identical_helper.sh '{}' "SOURCE_DIR" "DEST_DIR" ';'