Se o seu comando touch suportar -h para nenhuma desreferência :
find . -depth -exec touch -h -r "$reference_file" {} +
touch -c -h -r "$reference_file" ..
(note que -h implica -c (para evitar a criação do arquivo se ele não existir com o NetBSD / FreeBSD, mas não com o GNU ou o busybox touch (embora com o GNU touch ele não crie arquivos e imprima uma mensagem de erro), adicionando -c aqui para maior portabilidade).
Ou com um único comando find que poderia reduzir o número de comandos touch sendo executados:
find .. . -depth \( ! -name .. -o -prune \) -exec touch -c -h -r "$reference_file" {} +
Isto é, adicione .. à lista de arquivos dados a find , mas diga find para podar (não desça a ele).
Para um diretório arbitrário (bem aquele cujo caminho não começa com - :
find "$dir/.." "$dir/" \( ! -name .. -o -prune \) \
-exec touch -c -h -r "$reference_file" {} +
(aqui usando $dir/ em vez de $dir para o caso em que $dir se refere a um symlink para um diretório).
Com o BSD find , você pode usar
find -f "$dir/.." -f "$dir/" \( ! -name .. -o -prune \) \
-exec touch -c -h -r "$reference_file" -- {} +
para evitar os problemas com $dir , começando com - .
Embora você também possa fazer isso:
(
cd -P -- "$dir/" &&
exec find .. . \( ! -name .. -o -prune \) \
-exec touch -c -h -r "$reference_file" {} +
)
(assumindo que $reference_file não é um caminho relativo).
Note que se $reference_file é um link simbólico, com GNU touch e -h , o tempo de modificação do symlink será usado (aquele do alvo seria usado sem -h ) enquanto com o NetBSD ( onde -h vem de ) e FreeBSD touch , o horário de modificação do destino é usado com ou sem -h .
Se estiver usando zsh , você pode usar sua globalização recursiva
autoload zargs
zargs -- $dir/{.,..,**/*(NDoN)} -- touch -c -h -r $reference_file --
(o oN para não classificar a lista pode ser omitido, apenas para otimização).
O ksh93 acabou por adicionar suporte para a globalização recursiva do zsh em 2005, com a opção globstar .
(set -o globstar; FIGNORE=
command -x touch -c -h -r "$reference_file" -- ~(N)"$dir"/**)
Observe, entretanto, que ksh incluirá todas as entradas . e .. aqui, então todos os diretórios serão tocados várias vezes.
bash eventualmente copiou o globstar do ksh93 em 2009, mas foi inicialmente / quebrado / no qual ele estava seguindo links simbólicos ao descer de diretórios. Foi fixado em 4,3 em 2014.
bash não tem o equivalente de zargs ou ksh93 command -x do zsh para dividir as linhas de comando, de modo a evitar os problemas lista de arges muito longos . Em um sistema GNU, você sempre pode usar o GNU xargs para isso:
xargs -r0a <(
shopt -s dotglob nullglob globstar
printf '%sfind . -depth -exec touch -h -r "$reference_file" {} +
touch -c -h -r "$reference_file" ..
' "$dir/"{.,..,**}
) touch -c -h -r "$reference_file" --
Agora, provavelmente ainda usaria find aqui. Além do pior desempenho, outro problema com globs é que erros (como acesso negado) ao atravessar a árvore de diretórios são silenciosamente ignorados.