Jak mogę wyświetlić listę plików, których nie ma dowiązań symbolicznych?


10

Mam duży katalog „myfiles” pełen różnych dokumentów i nie chcę modyfikować jego struktury.

Dlatego stworzyłem (kilka) innych katalogów dla każdej klasy dokumentów. Na przykład mam katalog „images”, który zawiera dowiązania symboliczne do każdego .jpglub .cr2pliku w katalogu „myfiles” plus inne pliki opisowe dla każdego dowiązania symbolicznego (o tej samej nazwie) z opisem i innymi metadanymi. Dowiązania symboliczne w katalogu / images mogą mieć inną nazwę niż oryginalny połączony plik.

Próbuję znaleźć najprostszy sposób, aby upewnić się, że każdy plik obrazu w katalogu „myfiles” ma dowiązanie symboliczne do katalogu „images”.

Zobacz przykład struktury folderów

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

powinien wynikać

/images/b_800x600.jpg
/images/b_800x600.desc
/images/c_3820x5640.cr2
/images/c_3820x5640.cr2

Nie jest to pełna odpowiedź, ale możesz zapisać wyniki find /myfiles -type fpliku do pliku, a następnie użyć go, find /images -type l -exec readlink {} \; | egrep myfilesaby uzyskać listę plików, które są dowiązane symbolicznie, /imagesa następnie iterować wyniki, wykonując sedkażdy z nich w celu usunięcia ścieżek w pierwszym zapisanym pliku, ponieważ są one już zapisane mieć dowiązanie symboliczne, a pozostałe pliki to pliki, które nie mają dowiązania symbolicznego.
Bratchley,

2
Czy możesz zamiast tego korzystać z linków twardych, więc możesz użyć licznika linków twardych, aby sprawdzić, czy masz linki? Za pomocą ls -lmożesz zobaczyć liczbę linków w drugiej kolumnie.
Lambert

Rób to, co mówi @Lambert. rmte katalogi dowiązań symbolicznych i używają pax -rwl -s "\|.*regex|modifes_filename|" /path/to/myfiles/*.jpg /path/to/jpg_dirna przykład twardych dowiązań z programowo zmienionymi nazwami plików tylko dla tych plików, które pasują do twoich plików jpg. Możesz z tego uzyskać znacznie więcej - na przykład grupowanie na podstawie czasów zmian itp.
Mikeserv

Odpowiedzi:


6

Jeśli dobrze zrozumiem pytanie, potrzebujesz plików w moich plikach, które nie mają dowiązań symbolicznych w obrazach:

#!/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"

Jest to zastrzeżenie, jeśli masz plik a.jpg w katalogu myfiles / 1 i masz dowiązanie symboliczne do tego pliku w katalogu images / 3 lub po prostu w images / plik nie zostanie zgłoszony z brakującym dowiązaniem symbolicznym.


Dzięki ! Tak, zrozumiałeś poprawnie. Blisko, ale nie do końca. Moja wina, nie twoja :-) Podany przykład pokazuje uproszczony katalog myfiles. W rzeczywistości pliki obrazów pod moimi plikami mogą znajdować się na dowolnym poziomie zagnieżdżonych katalogów.
Robert Alexander

Zredagowałem odpowiedź, aby przeszukać całe moje pliki, ale sprawdź, czy tego właśnie chcesz.
taliezin

PRAWIE tam :-) Twój czkawka skryptu, gdy pliki mają spacje (i może inne bzdury, takie jak pojedyncze apostrofy "w nich ...
Robert Alexander

Myślę, że teraz powinno być ok
taliezin

Twoja ostatnia modyfikacja dzieli każdą f przy okazji każdej litery n! :-) Podłączyłem linię IFS do IFS = następnie nową linię z klawiatury, a potem kolejną ". Teraz podział wydaje się działać, ale otrzymuję długą sekwencję" missinglinks.sh: 11: missinglinks.sh: [[: not found „
Robert Alexander

3

Zakładam, że pliki poniżej myfilesnie są dowiązaniami symbolicznymi i że żadna z nazw plików nie zawiera nowych linii. (Moje podejście może nadal działać, jeśli te założenia zostaną naruszone, ale staje się bardziej skomplikowane.) Zakładam również, że masz wspólne readlinknarzędzie i obsługuje -fon kanonalizację ścieżek, co ma miejsce w Linuksie (zarówno GNU, jak i BusyBox), ale nie na np. OSX.

Zbuduj listę plików i posortuj ją dla pewności:

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

Zbuduj listę dowiązań symbolicznych z bezwzględnymi ścieżkami.

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

Lista plików, które nie są połączone:

comm -32 all.list linked.list

Jeśli używasz powłoki obsługującej podstawianie procesów, możesz umieścić wszystko w jednym poleceniu:

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

Jeśli poniższe linki /imagessą bezwzględne, możesz używać readlinkbez -fopcji, która jest dostępna w * BSD i OSX.


Miałem zamiar opublikować coś takiego, jak twoje commpolecenie, ale nie będę teraz, kiedy widzę, że już to zrobiłeś. Jednak przekierowanie z sortnie ma sensu; wtedy podstawienia procesu nic nie wyprowadzą. Możesz także dodać wiele katalogów obok, /imagesjeśli chcesz znaleźć pliki, w /myfilesktórych nie ma dowiązań symbolicznych z żadnego z wielu katalogów oprócz /images.
tripleee

1
Zobacz stackoverflow.com/questions/7665/ ... alternatywy dlareadlink -f
tripleee

@tripleee Zapomniałem usunąć przekierowanie, gdy zbudowałem wersję przekierowania procesu, dzięki. Tak, możesz łatwo dodawać inne katalogi lub dokonywać innych zmian.
Gilles „SO- przestań być zły”
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.