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

10

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

Portanto, criei (vários) outros diretórios para cada classe de documentos. Por exemplo, eu tenho um diretório "images" que possui links simbólicos para cada arquivo .jpgou .cr2no diretório "myfiles", além de 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 todos os arquivos de imagem no diretório "myfiles" tenham um link simbólico para o 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
Robert Alexander
fonte
Não é uma resposta completa, mas você pode salvar os resultados de a find /myfiles -type fem um arquivo e usá find /images -type l -exec readlink {} \; | egrep myfiles-lo para obter uma lista de arquivos com links simbólicos /imagese iterar sobre os resultados, fazendo um sedem cada um para excluir os caminhos no primeiro arquivo salvo, já que eles já tem o link simbólico e os arquivos restantes são os que não possuem o link simbólico.
Bratchley
2
É possível usar links físicos, para que você possa usar o contador de links físicos para ver se possui links? Usando ls -lvocê pode ver a contagem de hardlinks na segunda coluna.
27515 Lambert
Faça o que @Lambert diz. rmesses diretórios de link simbólico e use, pax -rwl -s "\|.*regex|modifes_filename|" /path/to/myfiles/*.jpg /path/to/jpg_dirpor exemplo, para obter links físicos com nomes de arquivos alterados programaticamente apenas para aqueles arquivos que correspondem aos seus jpgs. Você pode obter muito mais do que fora dela - como lotes com base em tempos de mudança e etc.
mikeserv

Respostas:

6

Se eu entendi bem a pergunta, você precisa de arquivos em meus arquivos que não possuem 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"

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

taliezin
fonte
Obrigado ! Sim, você entendeu corretamente. Perto, mas não exatamente. Minha culpa não é sua :-) O exemplo que dei mostra um diretório simplista de arquivos. Na realidade, os arquivos de imagem em myfiles podem estar em qualquer nível arbitrário de diretórios aninhados.
Robert Alexander
Editei a resposta para pesquisar em todos os meus arquivos, mas verifique se é isso que você deseja.
taliezin
Quase lá :-) seus soluços de script quando os arquivos têm espaços (e talvez outras tretas, como apóstrofos single" neles ...
Robert Alexander
Eu acho que agora deve ficar tudo bem #
28815 taliezin
Sua última modificação divide todos os f na ocorrência de cada letra n! :-) Alterei a linha do IFS para IFS = depois uma nova linha do teclado e depois outra ". Agora a divisão parece funcionar, mas recebo uma longa sequência de" missinglinks.sh: 11: missinglinks.sh: [[: not found "
Robert Alexander
3

Presumo que os arquivos abaixo myfilesnão sejam links simbólicos e que nenhum dos nomes de arquivos contenha novas linhas. (Minha abordagem ainda pode funcionar se essas suposições forem violadas, mas ficarem mais complicadas.) Suponho também que você tenha o readlinkutilitário comum e que suporte -fpara canonizar caminhos, como é o caso do Linux (GNU e BusyBox), mas não por exemplo, OSX.

Crie uma lista de arquivos e classifique-a como 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

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

comm -32 all.list linked.list

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

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

Se os links abaixo /imagesforem absolutos, você poderá usar readlinksem a -fopção, disponível em * BSD e OSX.

Gilles 'SO- parar de ser mau'
fonte
Eu estava prestes a postar algo como o seu commcomando, mas não vou agora que vejo que você já o fez. No entanto, o redirecionamento de sortnão faz sentido; as substituições do processo não produzirão nada. Além disso, você pode adicionar muitos diretórios ao lado, /imagesse desejar encontrar arquivos nos /myfilesquais não há links simbólicos para qualquer um de vários diretórios além /images.
tripleee
1
Veja stackoverflow.com/questions/7665/… para alternativas areadlink -f
tripleee
@tripleee Eu esqueci de fazer o redirecionamento quando construí a versão de redirecionamento de processo, obrigado. Sim, você pode adicionar facilmente outros diretórios ou fazer outras variações.
Gilles 'SO- stop be evil'