Niedawno przekonwertowałem wszystkie moje pliki FLAC na niższą częstotliwość próbkowania 44,1 kHz i głębię bitową 24 bity (ponieważ iPhone / iPod nie obsługują niczego powyżej) za pomocą XLD na moim Mac OS 10.7 (Lion).
Chociaż powiedziałem XLD, aby nadpisał wszystkie poprzednie pliki, XLD dodał (1)
na końcu bardzo podobny plik z
some_song.m4a
do
some_song(1).m4a
Teraz chcę usunąć to (1)
ze wszystkich przekonwertowanych plików FLAC.
Wiem, że prawdopodobnie mogłem użyć jakiegoś programu lub nawet AppleScript do zmiany nazwy plików, ale chciałem nauczyć się używać starej linii poleceń.
Wiem, że find . -name *\(1\).m4a
pobierze cały przekonwertowany plik FLAC.
Następnie wiem, że muszę coś zrobić -exec
i mv
zmienić nazwy wszystkich znalezionych plików. Ale nie mogę zrozumieć, jak zachować oryginalną nazwę pliku i usunąć tylko (1)
.
Może muszę zrobić przechwytywanie wyrażeń regularnych grup, aby zapisać część nazwy pliku, której nie chcę modyfikować? A może nie da się zrobić wszystkiego w jednym wierszu i powinienem utworzyć skrypt powłoki (co nie jest tak wygodne, ale chętnie spróbuję).
Wszelkie wskazówki i sugestie są mile widziane! Dzięki!
find
), ale może to rozwiązać Twój rzeczywisty problem (konwersja plików audio), możesz zainteresować się audiotools.sourceforge.net i przykładem tego (dla lwa MacosxOdpowiedzi:
Nie próbuj analizować
find
danych wyjściowych, chyba że w ostateczności. Ważne jest, aby zdawać sobie sprawę, że w systemach plików Unix nazwy plików nie są ciągami znaków (powszechne nieporozumienie), ale raczej binarnymi blokami BLOB, które mogą zawierać dowolny znak oprócz/
znaku null. Bezpieczna i prawidłowa analiza nazw plików jest wystarczającym problemem, że w 99% przypadków będziesz chciał całkowicie tego uniknąć (wystarczy spojrzeć na to, jak owłosione jestsed
wyrażenie w odpowiedzi @ yarka, a nawet to nie obejmuje wszystkich przypadków) . Na szczęście w tym przypadku istnieje znacznie prostsze podejście:źródło
done
?sed
podejściem do rur polega na tym, że jest to znacznie bezpieczniejsze. Nadal jest łatwiejszy do odczytania niż regexowa zupa z odwrotnym ukośnikiem, pod warunkiem, że rozumiesz podstawowe konstrukcje skryptowe powłoki.$arg
zmienna znacznie ułatwia odczyt.find
wywołujesh
przy użyciu dość przenośnej składni POSIX. Aby uzyskać więcej informacji, możesz sprawdzić sekcję Rozszerzanie parametrów , sekcję dotyczącą poleceń złożonych, która wyjaśniafor
pętlę , oraz specyfikację POSIXfind
. Oprócz tych zasobów chętnie odpowiem na wszelkie Twoje pytania.W systemach Debian i Ubuntu mogę użyć
rename 's/\(1\)//' *.m4a
rozwiązania problemu.źródło
man rename
, ale tak naprawdę nie mamrename
:-bash: rename: command not found
(which rename
nic nie pokazuje).man -a rename
znajduje rename (2) - syscall, a rename (n) - polecenie TCL. Nie ma tam ani zmiany nazwy (1), ani samego narzędzia.rename
to skrypt perla dołączony do przykładów zawartych w niektórych instalacjach perla, a kilka dystrybucji zawiera go na ścieżce, ponieważ jest to wygodne polecenie. (@Hobbes być może można go znaleźć w Internecie)rename
jest normalnym plikiem binarnym (nie perl). Kolejnym zastrzeżeniem jest to, że nie wszystkie wersjerename
wyrażeń regularnych obsługują. Na przykład wersja, którą mam, pozwala tylko na bezpośrednią zamianę łańcucha, np.rename '(1)' '' *.m4a
rename
Skrypt Perla jest instalowany tylko przez Debian i pochodne. Inne systemy Linux mają innerename
narzędzie (pokazane przez Patricka). OSX nie ma żadnego.W Zsh , używając Zmv :
W drugim argumencie (nowa nazwa)
$1
i$2
odwołaj się do grup(PATTERN)
w nawiasach we wzorcu źródłowym. Innym sposobem napisania tej zmiany jestźródło
Poniższe podejście umożliwia podgląd / przycinanie wygenerowanych poleceń przed ich wykonaniem i jest bardzo przenośne: powinno działać nie tylko na Macu, nie tylko z bash, i nie tylko z GNU sed; nawet w systemach bez
find
poleceniadu
(1) można bez problemu zastąpić go (1).Jeśli jesteś zadowolony z wydrukowanych poleceń, uruchom ponownie z
| sh -x
dołączonym.Jeśli martwisz się spacjami w nazwach plików, dodaj kolejne s, aby uciec ze wszystkich spacji:
Jeśli spodziewane są inne znaki specjalne, staje się to nieco trudniejsze:
Pierwsza funkcja konwertuje wszystko
'
do postaci takiej, że są one brane dosłownie, gdy znajdują się w środku'...'
łańcucha w kształcie ciągu. Druga funkcja generuje polecenia mv , których argumenty są zawarte w środku'...'
.źródło
(
i wszystkich innych znaków specjalnych) ani nie dodaje cudzysłowów wokół nazwy pliku. Próbowałem zmodyfikować twoje polecenie, ale nie mogłem wymyślić, jak dodać cudzysłowy do obu nazw plików dlamv
polecenia. Jednym z wynikowych wyników twojego polecenia jestmv ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us(1).m4a ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us.m4a
. A jeśli wykonam to polecenie, dostanę-bash: syntax error near unexpected token '('
.e
polecenie po podstawieniu. Na przykładfind . -name '*(1).m4a' | sed 's/\(.*\)(1).m4a$/mv & \1.m4a/e'
wykona polecenie exexcute bez potokowania dosh -x
.Oto mały skrypt, który to robi:
źródło
`find ...`