Jak zamienić jeden znak na inny we wszystkich nazwach plików w bieżących katalogach?


41

Jak zmienić nazwę wszystkich plików / podkatalogów w bieżącym folderze?

Powiedzmy, że mam wiele plików i podkatalogów ze spacjami i chcę zastąpić wszystkie spacje znakiem podkreślenia.

File 1
File 2
File 3
Dir 1
Dir 3

należy zmienić nazwę na

File_1
File_2
File_3
Dir_1
Dir_3

Odpowiedzi:


36

Jeśli musisz zmienić nazwy plików również w podkatalogach, a Twój predykat findobsługuje -execdir, możesz to zrobić

find /search/path -depth -name '* *' \
    -execdir bash -c 'mv -- "$1" "${1// /_}"' bash {} \;

Dziękuję @glenn jackman za zasugerowanie -depthopcji findi skłonienie mnie do myślenia.

Zauważ, że w niektórych systemach (w tym GNU / Linux) findmoże nie być w stanie znaleźć plików, których nazwa zawiera spacje, a także sekwencje bajtów, które nie tworzą prawidłowych znaków (typowe dla plików multimedialnych o nazwach ze znakami spoza ASCII zakodowanych w zestawie znaków inne niż ustawienia regionalne). Ustawienie ustawień regionalnych na C(jak w LC_ALL=C find...) rozwiązałoby problem.


Będziesz musiał użyć, find -maxdepth 1aby zrobić dokładnie to, o co OP poprosił o działanie w bieżącym folderze.
Caleb,

1
Użyj -depthopcji znajdź , a możesz się go pozbyć sort.
glenn jackman

@glenn jackman: dziękuję, teraz rozumiem, że moje rozwiązanie było złe.
enzotib

2
Zmień -name '* *'na -name '*_*'i zmień "${1// /_}"na"${1//_/.}"
enzotib

1
@kroiz: nazywa się to „podstawieniem wzorca”. Możesz go znaleźć na bashstronie podręcznika użytkownika.
enzotib

34

W dowolnej powłoce możesz przeglądać pliki, których nazwa zawiera spację. Zamiana spacji na znaki podkreślenia jest łatwa w bash, ksh i zsh za pomocą ${VARIABLE//PATTERN/REPLACEMENT}konstruktu.

for x in *" "*; do
  mv -- "$x" "${x// /_}"
done

Na Debianie, Ubuntu i pochodnych możesz używać Perla rename(inne dystrybucje dostarczają inny program jako rename, a ten program nie jest tutaj pomocny).

rename 's/ /_/g' *

Obowiązkowe rozwiązanie Zsh:

autoload zmv
zmv '(*)' '${1// /_}'

Obowiązkowe rozwiązanie POSIX:

for x in *" "*; do
  y=$(printf %sa "$x" | tr " " "_")
  mv -- "$x" "${y%a}"
done

Co oznacza „g” na końcu polecenia „zmień nazwę”? Nie widziałem tego w instrukcji.
JulianLai

Jak zmienić nazwę tylko katalogu? Nie chcę zmieniać nazwy pliku.
JulianLai

@JulianLai s/…/…/goznacza zastąpienie wszystkich wystąpień. Nie jest to dobrze wyjaśnione w instrukcji . Jeśli chcesz zmienić nazwy katalogów, istnieją sposoby, poszukaj go (myślę, że już go widziałem), a jeśli nie możesz go znaleźć, zadaj nowe pytanie.
Gilles „SO- przestań być zły”

świetnie ... pomogło mi to zmienić nazwę wszystkich _MG_blah.JPGna IMG_blah.JPG.
Abinash Dash

13

Możesz renamedo tego użyć (tutaj zakładając, że ten z util-linux, nie ten perl):

cd /path/to/dir
rename ' ' _ *\ *

Spowoduje to znalezienie przestrzeni wszystkich plików i katalogów w nazwie i zastąpienie spacji znakiem podkreślenia. Ponieważ korzysta z dopasowywania plików glob, na początek musisz znajdować się w odpowiednim katalogu.

Jeśli chcesz wykonywać rekurencyjne dopasowania, możesz, ale może być konieczne wykonanie renamekilku razy, aby złapać dowolne elementy w katalogach, których nazwy zostały zmienione:

cd /path/to/dir
shopt -s globstar
rename ' ' _ **/*\ *
!!; !!

2
renameZmieni nazwy określonych plików, zastępując pierwsze wystąpienie z w ich nazwie słowem„ do ”. To będzie działać tylko w przypadku plików z pojedynczą spacją w nazwie. (Możesz zadzwonić renamew pętli, ale tak naprawdę nie jest to właściwe narzędzie.)
SO Gillesa - przestań być zły ”


1

Na Debianie / Ubuntu, w oparciu o odpowiedzi Caleba i Gillesa, działało dla mnie, aby zmieniać nazwy plików rekurencyjnie:

cd /path/to/dir
shopt -s globstar
rename 's/ /_/g' **

Uwaga: Aby wyświetlić podgląd plików, które zostaną przemianowane i jak, użyj -nprzełącznika z rename:

rename -n 's/ /_/g' **

Inna uwaga: ustawienie globstarpowoduje, że **pliki dopasowania są we wszystkich podkatalogach, więc jeśli pożądany jest tylko bieżący katalog, nie ustawiaj globstar ani nie używaj *zamiast niego **.

Jeszcze jedna uwaga: renamepolecenie musi zostać uruchomione więcej niż jeden raz dla plików z wieloma wystąpieniami wyszukiwanego terminu.


Działa to tylko wtedy, gdy katalogi nie zawierają spacji. (zmiana nazwy na a b/c dna a_b/c_dnie działa, musisz najpierw zmienić nazwę a b/c dna a b/c_d, a następnie a bna a_b).
Stéphane Chazelas,

@Stephane: Czy oznacza to renamedwukrotne uruchomienie tego samego polecenia?
Markus Pscheidt,

Cóż, mniej więcej tyle razy, ile jest zagnieżdżonych poziomów katalogów ze spacjami. Najlepiej jest najpierw przejść przez głębokość katalogu i przekonwertować tylko nazwę bazową pliku, tak jak w zaakceptowanym rozwiązaniu. Zauważ też, że bash **wyklucza pliki kropkowe i trawersuje dowiązania symboliczne.
Stéphane Chazelas,

0

Jeśli nie masz flasha na wyrażeniach regularnych (nie jestem!) I możesz uruchamiać aplikacje zaprojektowane dla KDE (albo używasz KDE - K Desktop, albo masz zainstalowane biblioteki), to Krename to świetne narzędzie graficzne, które pozwala zobaczyć przed i po przed zobowiązać się do zmian. Ma wiele prostych przekształceń jako opcji, a także obsługuje wyrażenia regularne. Możesz nawet połączyć kilka kolejnych transformacji w jedną zmianę nazwy, więc nie musisz projektować jednej złożonej transformacji, która robi to wszystko jednocześnie. Ma również opcję kontynuowania zmiany nazw tych samych plików po zastosowaniu zmiany nazwy.

Nie używam go tak często, ale kiedy to robię, naprawdę szybko i łatwo wykonuje pracę. Naprawdę przydaje się przy zmianie nazw różnych pobranych plików multimedialnych, aby można było nimi jednolicie zarządzać w systemie. Pomaga osobno pobrać instrukcję krename, dzięki czemu można się do niej odwoływać podczas korzystania z programu.

http://www.krename.net/

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.