Jak Bash może zmienić nazwę serii pakietów, aby usunąć ich numery wersji? Bawiłem się obydwoma expr
i %%
bezskutecznie.
Przykłady:
Xft2-2.1.13.pkg
staje się Xft2.pkg
jasper-1.900.1.pkg
staje się jasper.pkg
xorg-libXrandr-1.2.3.pkg
staje się xorg-libXrandr.pkg
bash
shell
file-rename
Jeremy L.
źródło
źródło
Odpowiedzi:
Możesz użyć funkcji rozszerzania parametrów basha
W przypadku nazw plików ze spacjami potrzebne są cudzysłowy.
źródło
rename "s/-[0-9.]*//" *.pkg
Jeśli wszystkie pliki znajdują się w tym samym katalogu, sekwencja
wykona twoją pracę. Polecenie sed utworzy sekwencję poleceń mv , którą możesz następnie przesłać do powłoki. Najlepiej jest najpierw uruchomić potok bez końcowego
| sh
, aby sprawdzić, czy polecenie robi to, co chcesz.Aby korzystać z wielu katalogów, użyj czegoś takiego jak
Zauważ, że w sed sekwencja grupowania wyrażeń regularnych jest poprzedzona nawiasami odwrotnymi,
\(
a\)
zamiast pojedynczych nawiasów(
i)
.źródło
ls
w skryptach. Pierwszą odmianę można osiągnąć przyprintf '%s\n' * | sed ...
odrobinie kreatywności i prawdopodobnie można się jej pozbyćsed
. Bashprintf
oferuje'%q'
kod formatu, który może się przydać, jeśli masz nazwy plików, które zawierają metaznaki powłoki dosłownie.Zrobię coś takiego:
przypuszczalnie cały twój plik znajduje się w bieżącym katalogu. Jeśli nie, spróbuj użyć funkcji find zgodnie z powyższymi zaleceniami Javiera.
EDYCJA : Ponadto ta wersja nie używa żadnych funkcji specyficznych dla basha, jak inne powyżej, co prowadzi do większej przenośności.
źródło
Oto niemal odpowiednik obecnie akceptowanej odpowiedzi POSIX . To zamienia
${variable/substring/replacement}
rozszerzenie parametrów tylko do Bash na takie, które jest dostępne w dowolnej powłoce kompatybilnej z Bourne.Interpretacja parametrów
${variable%pattern}
daje wartośćvariable
z dowolnym sufiksem, który pasuje,pattern
usunięty. (Należy również${variable#pattern}
usunąć przedrostek).Zachowałem wzór podrzędny
-[0-9.]*
z zaakceptowanej odpowiedzi, chociaż może jest to mylące. To nie jest wyrażenie regularne, ale wzorzec glob; więc nie oznacza „myślnika, po którym następuje zero lub więcej cyfr lub kropek”. Zamiast tego oznacza „myślnik, po którym następuje liczba lub kropka i cokolwiek”. „Cokolwiek” będzie najkrótszym możliwym dopasowaniem, a nie najdłuższym. (Bash oferuje##
i%%
przycinanie najdłuższego możliwego przedrostka lub sufiksu zamiast najkrótszego).źródło
Możemy założyć, że
sed
jest dostępny na dowolnym * nix, ale nie możemy być pewni, że będzie obsługiwałsed -n
generowanie poleceń mv. ( UWAGA:sed
robi to tylko GNU ).Mimo to, bash builtins i sed, możemy szybko uruchomić funkcję powłoki, aby to zrobić.
Stosowanie
Tworzenie folderów docelowych:
Ponieważ
mv
nie tworzy automatycznie folderów docelowych, nie możemy używać naszej początkowej wersjisedrename
.To dość mała zmiana, więc fajnie byłoby uwzględnić tę funkcję:
Będziemy potrzebować funkcji narzędzia
abspath
(lub ścieżki bezwzględnej), ponieważ bash nie ma tej wbudowanej .Gdy już to zrobimy, możemy wygenerować folder docelowy (i) dla wzorca sed / rename, który zawiera nową strukturę folderów.
Dzięki temu będziemy znać nazwy naszych folderów docelowych. Kiedy zmienimy nazwę, będziemy musieli użyć jej na docelowej nazwie pliku.
Oto skrypt obsługujący pełny folder ...
Oczywiście nadal działa, gdy nie mamy również określonych folderów docelowych.
Gdybyśmy chcieli umieścić wszystkie utwory w folderze,
./Beethoven/
możemy to zrobić:Stosowanie
Runda bonusowa ...
Użycie tego skryptu do przenoszenia plików z folderów do jednego folderu:
Zakładając, że chcieliśmy zebrać wszystkie pasujące pliki i umieścić je w bieżącym folderze, możemy to zrobić:
Uwaga na temat wzorców sed regex
W tym skrypcie obowiązują regularne reguły wzorca sed, te wzorce nie są PCRE (wyrażenia regularne zgodne z Perlem). Możesz mieć rozszerzoną składnię wyrażeń regularnych sed, używając jednej z nich
sed -r
lub wsed -E
zależności od platformy.man re_format
Pełny opis podstawowych i rozszerzonych wzorców regexp sed można znaleźć w dokumencie zgodnym z POSIX .źródło
Uważam, że zmiana nazwy jest znacznie prostszym narzędziem do tego typu rzeczy. Znalazłem to na Homebrew dla OSX
Dla twojego przykładu zrobiłbym:
„S” oznacza substytut. Formularz to s / searchPattern / replace / files_to_apply. W tym celu musisz użyć wyrażenia regularnego, co wymaga trochę przestudiowania, ale jest warte wysiłku.
źródło
for
ised
itd. Jest w porządku, ale jest to znacznie szybciej i proste wystarczy użyćrename
, jeśli znajdziesz się robić to częściej.rename
polecenie; dodatkowo, niektóre będą miały innerename
polecenie z różnymi funkcjami, składnią i / lub opcjami. To wygląda jak Perl,rename
który jest dość popularny; ale odpowiedź powinna naprawdę to wyjaśnić.lepsze użycie
sed
do tego, coś takiego:ustalenie wyrażenia regularnego pozostawia się jako ćwiczenie (podobnie jak w przypadku nazw plików zawierających spacje)
źródło
Wydaje się, że to działa, zakładając, że
zdejmij .pkg, a następnie - ..
źródło
-e
. Npsed -e 's/\.pkg//g' -e 's/-.*//g'
.ls
wyników i nie cytuj swoich zmiennych. Zobacz także shellcheck.net, aby zdiagnozować typowe problemy i antywzory w skryptach powłoki.Miałem wiele
*.txt
plików do zmiany nazwy, tak jak.sql
w tym samym folderze. poniżej pracował dla mnie:źródło
Dziękuję za te odpowiedzi. Miałem też jakiś problem. Przenoszenie plików .nzb.queued do plików .nzb. W nazwach plików były spacje i inne nierówności, a to rozwiązało mój problem:
Opiera się na odpowiedzi Diomidisa Spinellisa.
Wyrażenie regularne tworzy jedną grupę dla całej nazwy pliku i jedną grupę dla części przed .nzb.queued, a następnie tworzy polecenie przesunięcia powłoki. Z cytowanymi łańcuchami. Pozwala to również uniknąć tworzenia pętli w skrypcie powłoki, ponieważ jest to już zrobione przez sed.
źródło
-n
opcji w ten sam sposób.