Zamień wszystkie dwukropki z nazw plików na terminal

12

Mam muzykę GB na moim dysku twardym sformatowanym w EXT4. Chcę przenieść te pliki na partycję HDD sformatowaną w systemie plików FAT. Jednak nie mogę przenieść większości moich plików, ponieważ mają one w nazwach „:” (na przykład „Akt 2: .....” w przypadku oper). Czy w wierszu polecenia można zmienić nazwę wszystkich moich plików z „XXXX: XXXX” na „XXXX-XXXX”?

Ryan McClure
źródło

Odpowiedzi:

25

Jeśli wszystkie twoje pliki znajdują się w jednym katalogu, spróbuj:

rename 's|:|-|g' *

(gdzie * można zmienić na coś bardziej restrykcyjnego, jeśli chcesz)

Jeśli masz wiele plików w drzewie katalogów, wypróbuj to od podstawy drzewa:

find . -name "*:*" -exec rename 's|:|-|g' {} \;

Możesz dodać tę opcję od -nrazu, renameaby poinformowała cię, co by ZROBIŁA bez AKTYWNEGO zrobienia tego. Może to pomóc uniknąć przypadkowego nadepnięcia na inne pliki lub coś innego złego ...

AeroGT80
źródło
1
Rozwiązanie pojedynczego katalogu będzie działać, ale rozwiązanie zagnieżdżone nie zadziała, jeśli same katalogi mają: s w swoich nazwach. Jest tak, ponieważ w danych wyjściowych find .nazwy podkatalogu poprzedza się jego zawartość. Więc jeśli masz plik /1:/2:najpierw /1:/zostanie zmieniona na /1-/. Teraz nie możesz zmienić nazwy /1:/2:na, /1-/2-ponieważ /1:/2:nie istnieje.
S Prasanth,
1
W przypadku katalogów: find . -type d -readable -writable -exec rename 's|:|-|g' {} \;a następnie plików:find . -type f -readable -writable -exec rename 's|:|-|g' {} \;
@Christopher Polecenie dla katalogów zakończy się niepowodzeniem, jeśli istnieją dwa poziomy katalogów z: w ich nazwach. Np .: / 1: / 2: / where 2: to także katalog. Oczywiście, jeśli tak nie jest w przypadku Ryana, to zadziała.
S Prasanth,
Dla wielu poziomów podrzędnych katalogów używać: for i in {1..20}; do find . -maxdepth $i -mindepth $i -name "*:*" -exec rename 's|:|-|g' {} \;; done. Zmień 20 na maksymalną głębokość reż. Struktura. Nie musi być dokładny - może być większy. Zajmie to jednak czas, jeśli zostanie ustawiony na bardzo dużą liczbę.
S Prasanth,
0

Nie jestem teraz w mojej maszynie z Linuksem, więc mogę podać tylko przybliżone informacje.

Linux ma narzędzie wiersza polecenia o nazwie, renamektóre działa z innymi danymi wejściowymi, wyrażeniami regularnymi lub wyrażeniami regularnymi. Powinieneś być w stanie użyć tego wraz z wyrażeniem regularnym, takim jak „s /: / - /” na swoich plikach, aby uzyskać pożądaną nazwę.

Na wszelki wypadek zrób to małymi partiami i / lub pierwszy test z symulacją (zmiana nazwy ma flagę, która podaje tylko starą nazwę i nową nazwę pliku bez faktycznej zmiany nazwy - użyj tego do sprawdzenia w pierwszej kolejności)

Karthik T.
źródło
0

Jest to rozwiązanie w Pythonie, które obsługuje przypadek, w którym pliki niekoniecznie znajdują się w tym samym katalogu.

import os
torename = []
rootdir = "The main directory"
logfile = "Path to log file" #Eg: logfile = "/home/prasanth/renamelog"
for (path, dirs, files) in os.walk(rootdir):
    for dirname in dirs:
        if ':' in dirname:
            torename.append(os.path.join(path, dirname))
    for filename in files:
        if ':' in filename:
            torename.append(os.path.join(path, filename))

print "No of files/dirs to rename =", len(torename)
a = raw_input("Continue? (y/n) ")
if a == 'y':
    torename.reverse()
    for oldname in torename:
        directory, filename = os.path.split(oldname)
        newname = os.path.join(directory, filename.replace(':', '-'))
        command = 'mv %s %s > /dev/null' % (repr(oldname), repr(newname))
        os.system(command)
        f = open(logfile, 'a')
        f.write(oldname + '\n')
        f.close()
else:
    print "Aborted."
  1. Zapisz to w pliku (powiedzmy) rename.py.
  2. Przejdź rootdirdo rozważanego katalogu najbardziej zewnętrznego (użyj pełnej nazwy ścieżki zaczynającej się od /. Nie wolno używać skrótów ani zmiennych env, takich jak ~). Nie trzeba umieszczać \ przed znakami specjalnymi - na przykład, jeśli najbardziej zewnętrzny katalog to /.../Mój dysk twardy, rootdir = "/.../My HDD"NIE umieszczaj rootdir = "/.../My\ HDD"(zwróć uwagę na „s”). (Mówię to wyraźnie tylko dlatego, że możesz nie znać języka Python. Nie lekceważ zamierzony.]
  3. Zmień logfileżądaną lokalizację pliku dziennika. Na koniec plik ten będzie zawierał listę plików o zmienionych nazwach - do wykorzystania w przyszłości.
  4. Zadzwoń python rename.py.

Ostrzeżenie: wykonaj test na małej próbce, zanim zaryzykujesz całą GB muzyki.

Szczegóły: zmiana nazwy odbywa się od najbardziej wewnętrznych plików na zewnątrz.

S Prasanth
źródło
0

Zdaję sobie sprawę, że to bardzo stary post. Rekurencyjne rozwiązanie AeroGT80 jest bardzo dokładne, ale działa dość wolno. Pracowałem przez około pół godziny na wolniejszym serwerze, a wykonałem tylko około połowy - myślę, że było to około 73 000 plików w około 300 podkatalogach.

Poniższe rozwiązanie będzie działać znacznie szybciej (działa na wszystkich plikach w katalogu, zamiast na każdym pliku jeden po drugim - przy użyciu nierekurencyjnego rozwiązania AeroGT80). Jedyny problem polega na tym, że zajmuje on tylko jeden katalog głęboko (więc nie jest w pełni rekurencyjny, jak jego rozwiązanie), ale jestem pewien, że można go łatwo zmodyfikować.

#!/bin/bash
for D in *; do
        if [ -d "${D}" ]; then
                #echo "${D}"
                pushd "${D}" > /dev/null
                rename 's|:|-|g' *
                popd > /dev/null
        fi
done
Adam Plocher
źródło