Zastosuj polecenie do wszystkich plików w katalogu, jeden katalog na raz

2

Chcę zastosować informacje o odtwarzaniu do wszystkich plików MP3 w mojej kolekcji muzycznej. Aby to zrobić, używam narzędzia o nazwie mp3gain (w systemie Linux).

Aby poprawnie zastosować wzmocnienie albumu, muszę uruchomić polecenie mp3gain dla poszczególnych katalogów. Innymi słowy, muszę znaleźć katalog, uruchomić mp3gain na wszystkich plikach w tym katalogu, a następnie powtórzyć dla każdego innego katalogu. Do tej pory wymyśliłem:

 find . -type d -exec mp3gain {}/*.mp3 \;

Dane wyjściowe wyglądają tak (pokazuje tylko kilka z wielu katalogów):

[...]
./dev2/Physicist/*.mp3
Can't open ./dev2/Physicist/*.mp3 for reading
./Real Things/*.mp3
Can't open ./Real Things/*.mp3 for reading

Wydaje mi się, że „ *” ucieka, więc zamiast szukać wszystkich plików z rozszerzeniem „.mp3”, szuka pliku o nazwie „ *.mp3”.

Jakiego polecenia powinienem użyć?

NickG
źródło
Zarówno John T, jak i michaelwells opublikowali rozwiązania, które działają dobrze, ale zaznaczyłem rozwiązanie Johna T jako prawidłowe, ponieważ odpowiedział jako pierwszy. Dziękuje wszystkim.
NickG

Odpowiedzi:

7

Wygląda na to, że nie globuje poprawnie. Co powiesz na coś takiego:

#!/bin/bash
OLDIFS=$IFS
IFS=$(echo -en "\n\b")
for dir in $(find . -type d)
do
        mp3gain $dir/*
done
IFS=$OLDIFS

jako jedno polecenie:

OLDIFS=$IFS;IFS=$(echo -en "\n\b");for dir in $(find . -type d);do mp3gain $dir/*;done;IFS=$OLDIFS
John T.
źródło
2
czy to odpowiednio obsłuży nazwy spacji w katalogu? nigdy nie udało mi się uzyskać bash dla pętli, aby NIE podzielić na spacje.
quack quixote
dobra decyzja. naprawiony!
John T
+1, fajne rozwiązanie. myślę, że 1-liniowy wymaga exporttych zmiennych (zakładając, że bash jest powłoką), ale poza tym wygląda to dobrze.
quack quixote
Powinieneś być w stanie to zrobićIFS=$'\n\b'
Dennis Williamson
@ ~ szarlatan: Nie ma potrzeby eksportowania tych zmiennych.
Dennis Williamson
1

To może nie wyglądać ładnie, ale to polecenie znajdzie wszystkie katalogi zawierające pliki mp3 zapisuje je w pliku tymczasowym, a następnie przegląda ten plik tymczasowy, wyświetlając zawartość każdego katalogu. Jeśli jesteś zadowolony z Output, możesz iść dalej i podłączyć do niego polecenie mp3gain zamiast ls.

Ustawienie zmiennej IFS na znak nowego wiersza jest ważne, aby można było pracować z plikami i katalogami zawierającymi spacje.

Powodem, dla którego wybrałem listę katalogów zawierających najpierw mp3, jest przypadek, gdy mp3gain zgłasza błąd przy napotkaniu pustych zestawów plików. W ten sposób nigdy nie napotyka takiej sytuacji.

IFS=$'\n'; for i in `find -type f -iname *.mp3`; do dirname $i ; done | sort | uniq > ~/mp3directories.txt && for i in `cat ~/mp3directories.txt`; do ls -1 $i/*.mp3 ; echo ; done
użytkownik19647
źródło
Jedynym problemem jest to, że chce zrobić to 1 katalog na raz. Jeśli nazwy plików zostaną posortowane, będą one pobierać je ze wszystkich różnych katalogów, zamiast przetwarzać każdy plik w jednym katalogu, a następnie przechodzić do następnego.
John T
Po pierwsze, dziękuję wam oboje za poświęcenie czasu na udzielenie odpowiedzi. John T, kod Michaelawellsa wyrzuca listę katalogów, a nie nazw plików. Przetestowałem to i robi to, co chciałem, chociaż tylko w katalogach zawierających pliki MP3.
NickG,