Tak, uporządkuję swoją muzykę. Wszystko ułożyłem pięknie w następującej mantrze: /Artist/Album/Track - Artist - Title.ext
a jeśli taka istnieje, pokrywa pozostaje w środku /Artist/Album/cover.(jpg|png)
.
Chcę przejrzeć wszystkie katalogi drugiego poziomu i znaleźć te, które nie mają okładki. Na drugim poziomie mam na myśli, że nie obchodzi mnie, czy /Britney Spears/
nie ma cover.jpg, ale byłbym zainteresowany, gdyby /Britney Spears/In The Zone/
go nie miał.
Nie przejmuj się pobieraniem okładek (jutro to dla mnie fajny projekt). Dbam tylko o chwalebną bzdurę o odwrotnym find
przykładzie.
Odpowiedzi:
Przypadek 1: Znasz dokładną nazwę pliku do wyszukania
Użyj za
find
pomocą,test -e your_file
aby sprawdzić, czy plik istnieje. Na przykład szukasz katalogów, w których nie ma żadnychcover.jpg
:Rozróżnia małe i wielkie litery.
Przypadek 2: Chcesz być bardziej elastyczny
Nie jesteś pewien sprawy, a rozszerzenie może być
jPg
,png
...Wyjaśnienie:
sh
dla każdego katalogu, ponieważ podczas korzystania z niego nie jest możliwe przesyłanie potokówfind
ls -1 "{}"
wypisuje tylko nazwy plików katalogu, któryfind
aktualnie przechodziegrep
(zamiastgrep
) używa rozszerzonych wyrażeń regularnych;-i
sprawia, że wyszukiwanie nie rozróżnia wielkości liter,-q
sprawia, że pomija jakiekolwiek dane wyjściowe"^cover\.(jpg|png)$"
jest wzorcem wyszukiwania. W tym przykładzie, pasuje npcOver.png
,Cover.JPG
albocover.png
..
Musi być uciekł w przeciwnym razie oznacza to, że pasuje dowolny znak.^
oznacza początek linii,$
jej koniecInne przykłady wzorca wyszukiwania dla egrep :
Zamień
egrep -i -q "^cover\.(jpg|png)$"
część na:egrep -i -q "cover\.(jpg|png)$"
: Pasuje takżecd_cover.png
,album_cover.JPG
...egrep -q "^cover\.(jpg|png)$"
: Dopasowujecover.png
,cover.jpg
ale NIECover.jpg
(rozróżnianie wielkości liter nie jest wyłączone)egrep -iq "^(cover|front)\.jpg$"
: Pasuje npfront.jpg
,Cover.JPG
ale nieCover.PNG
Aby uzyskać więcej informacji na ten temat, sprawdź Wyrażenia regularne .
źródło
test
.-exec bash -c '[[ -n $(find "{}" -iname "cover.*") ]]' \;
ale jest to dość brudne pod względem optymalizacji. Ale to działa.test
ładunek-o EXPRESSION
zapytań OR ... np.:test -e "{}/cover.jpg" -o -e "{}/cover.png"
Co jest lepsze niż przeprowadzanie pełnego wyszukiwania, ale nadal rozróżnia małe i wielkie litery.$
nazwę dir (na przykład Ke $ ha).Proste, okazuje się. Poniżej przedstawiono listę katalogów z okładką i porównuje ją z listą wszystkich katalogów drugiego poziomu. Linie pojawiające się w obu „plikach” są pomijane, pozostawiając listę katalogów, które wymagają okładek.
Brawo.
Uwagi:
comm
Argumenty są następujące:-1
pomija wiersze unikalne dla pliku 1-2
pomija wiersze unikalne dla file2-3
pomija linie pojawiające się w obu plikachcomm
pobiera tylko pliki, stąd kooky<(...)
metoda wprowadzania. Spowoduje to przesłanie zawartości przez prawdziwy [tymczasowy] plik.comm
wymaga posortowanych danych wejściowych lub nie działa ifind
w żadnym wypadku nie gwarantuje zamówienia. Musi także być wyjątkowy. Pierwszafind
operacja może znaleźć wiele plików,cover.*
więc mogą istnieć zduplikowane wpisy.sort -u
szybko potrząsa nimi do jednego. Drugie znalezisko zawsze będzie wyjątkowe.dirname
jest przydatnym narzędziem do uzyskania katalogu pliku bez uciekania się dosed
(i in.).find
icomm
oba są nieco niechlujne z ich wynikami. Ostatecznymsed
zadaniem jest posprzątanie rzeczy, więc nie masz nicArtist/Album
. To może być lub może nie być dla Ciebie pożądane.źródło
find
można uprościćfind ~/Music/ -iname 'cover.*' -printf '%h\n'
, unikając takiej potrzebydirname
. chociażdirname
jest przydatny gdzie indziej.Jest to o wiele łatwiejsze do rozwiązania z globowaniem niż z find.
Załóżmy teraz, że w tej ładnej strukturze nie ma zbłąkanych plików. Bieżący katalog zawiera tylko podkatalogi wykonawców, a te zawierają tylko podkatalogi albumów. Następnie możemy zrobić coś takiego:
<(...)
Składnia jest Bash podstawienie proces: to pozwala użyć polecenia zamiast argumentu plikowego. Pozwala traktować dane wyjściowe polecenia jako plik. Możemy więc uruchomić dwa programy i pobrać ich różnice bez zapisywania ich wyników w plikach tymczasowych.diff
Program myśli, że pracuje z dwoma plikami, ale w rzeczywistości jest to odczyt z dwóch rur.Polecenie to powoduje wejście prawą rękę
diff
,printf "%s\n" */*
tylko wymienia katalogi album. Polecenie po lewej stronie wykonuje iterację*.cover
ścieżek i wypisuje nazwy katalogów.Testowe uruchomienie:
Aha,
a/b
ifoo/bar
katalogi nie mającover.jpg
.Istnieją przypadki łamania narożników, takie jak to, że domyślnie
*
rozwija się do siebie, jeśli nie pasuje do niczego. Można to rozwiązać za pomocą Bashaset -o nullglob
.źródło
comm
byłyby czystsze niżdiff
?comm -3 <(printf "%s\n" */*/cover* | sed -r 's/\/[^\/]+$//' | sort -u) <(printf "%s\n" */*)
wydaje się rozsądnym kompromisem bezdiff
puchu. Jest jednak trochę wolniejszy niż moje podwójne znalezisko.Pokaże wszystkie katalogi, w których nie ma plików txt.
źródło