Como posso listar arquivos dos quais não existem links simbólicos?

8

Eu tenho um grande diretório "myfiles" cheio de documentos miscelâneos e não quero modificar sua estrutura.

Por isso, criei (vários) outros diretórios para cada classe de documentos. Por exemplo, eu tenho um diretório "images" que possui symlinks para cada arquivo jpg ou cr2 no diretório "myfiles" mais outros arquivos descritivos para cada link simbólico (com o mesmo nome de arquivo) com descrição e outros metadados. Os links simbólicos no diretório / images podem ter um nome diferente do arquivo vinculado original.

Estou tentando encontrar a maneira mais simples de garantir que cada arquivo de imagem no diretório "myfiles" tenha um link simbólico no diretório "images".

Veja um exemplo da estrutura de pastas

/myfiles/a.doc
/myfiles/b.jpg
/myfiles/c.cr2
/myfiles/d.mov

deve resultar

/images/b_800x600.jpg
/images/b_800x600.desc
/images/c_3820x5640.cr2
/images/c_3820x5640.cr2
    
por Robert Alexander 27.03.2015 / 15:09

2 respostas

5

Se eu entendi bem a questão, você precisa de arquivos em myfiles que não possuam links simbólicos nas imagens:

#!/bin/bash

OIFS="$IFS"
IFS=$'\n'

files="$(find myfiles/ -type f -name '*.jpg' -or -name '*.cr2')"
for f in $files; do
    list="$(find -L images/ -xtype l -samefile "$f")"
    if [[ "$list" == "" ]]; then
        echo "$f does not have symlink."
    fi
done

IFS="$OIFS"

Existe uma ressalva com esta abordagem se você tiver o arquivo a.jpg no diretório myfiles / 1 e você tiver um link simbólico para esse arquivo no diretório images / 3 ou simplesmente em imagens / o arquivo não será reportado com o symlink ausente.

    
por 27.03.2015 / 21:29
3

Suponho que os arquivos em myfiles não sejam links simbólicos e que nenhum dos nomes de arquivo contenha novas linhas. (Minha abordagem ainda pode funcionar se essas suposições forem violadas, mas fica mais complicado.) Suponho também que você tem o utilitário readlink comum e que ele suporta -f para canonicalizar caminhos, que é o caso do Linux (ambos GNU e BusyBox), mas não em, por exemplo OSX.

Crie uma lista de arquivos e classifique-a para uma boa medida:

find /myfiles -type f -print | sort >all.list

Crie uma lista de destinos de links simbólicos, com caminhos absolutos.

find /images -type f -exec readlink -f {} \; | sort >linked.list

Listar os arquivos que não estão vinculados:

comm -32 all.list linked.txt

Se você usar um shell que suporte a substituição de processos, poderá colocar tudo em um único comando:

comm -23 <(find /myfiles -type f -print | sort) \
         <(find /images -type f -exec readlink -f {} \; | sort)

Se os links em /images forem absolutos, você pode usar readlink sem a opção -f , que está disponível em * BSD e OSX.

    
por 28.03.2015 / 01:45