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.