Odpowiedzi:
rename
Narzędzie, że statki z Ubuntu jest dość gorąco w tego rodzaju rzeczy. Możesz osadzić małe wyrażenia Perla, takie jak:
rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *
To po prostu pokaże ci, co by to zrobił. Usuń, -n
aby uczynić z niego ćwiczenie na żywo.
Zasadniczo działa to poprzez wstępne zdefiniowanie zmiennej i zwiększenie jej z każdym trafionym plikiem. Jeśli masz więcej niż 10 plików, sugeruję użycie dopełniania zerowego w sprintf
. Następujące są dobre do 999
:
rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *
... Ale to dość łatwe do rozszerzenia.
Aby poprawić @ Oli odpowiedzi The rename
narzędzie wersja 1.600 przez Arystotelesa Pagaltzis faktycznie ma wbudowany licznik, $N
.
Wszystko czego potrzebujesz to
rename 's/AS.*/AS$N/' *
Żeby zainstalować,
brew install rename
lub Pobierz skrypt/usr/local/bin/brew
lub /usr/bin
)rename
pozwala przypisać bezpośrednio do $_
, co jest idealne na ten problem.Chociaż argumenty kod przechodzimy do Perl rename
użyteczności często wykonują dopasowanie i podstawienie (Z s/
), i jest to całkowicie dopuszczalne , aby rozwiązać ten problem w ten sposób , to naprawdę nie ma potrzeby, że w przypadkach takich jak ten, gdzie nie jesteś rzeczywiście badania lub ponowne użycie tekstu starych nazw plików. rename
pozwala pisać prawie o każdym kodzie Perla i nie musi być osadzony w środku s/
/e
. Sugeruję użycie następującego polecenia:
rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *
Lub, jeśli masz ochotę zgolić kilka postaci:
rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *
(Może być jeszcze krótszy, ale nie bez utraty jasności).
Oba te polecenia robią to samo. Każdy pokazuje, jakie operacje zmiany nazwy zostaną podjęte. Gdy wypróbujesz jeden i będziesz zadowolony z wyników, uruchom go ponownie bez -n
opcji. Jak napisano, byłoby to produkować nazwy plików AS01.txt
, AS02.txt
, ..., AS10.txt
, AS11.txt
, i tak dalej. Możesz je modyfikować w razie potrzeby, a następnie usuwać tylko -n
wtedy, gdy podoba Ci się to, co widzisz.
Jeśli chcesz wypełnić pad większą niż 2, zamień na 2
większą liczbę. Na przykład, jeśli z jakiegoś powodu chciałbyś mieć nazwy plików AS00000000000001.txt
, zastąpiłbyś %02d
je %014d
. Jeśli w ogóle nie chcesz wypełnienia - nawet jeśli to sprawi, że Twoje pliki pojawią się w kolejności nienumerycznej, gdy będziesz je później wyświetlać na liście! - możesz zastąpić %02d
je właśnie %d
.
Jak to działa? Twoja powłoka rozwija *
się do listy plików, zanim uruchomi nawet rename
polecenie. Lista jest posortowana leksykograficznie (tj. Alfabetycznie) zgodnie z bieżącymi ustawieniami regionalnymi. rename
odbiera nazwy plików jako argumenty wiersza poleceń i przetwarza je w kolejności, w jakiej są wymienione. Wyrażenie ++$i
zwraca wartość o jedną większą niż bieżąca wartość zmiennej $i
, a także ustawia zmienną $i
na tę nowo zwiększoną wartość. Ta wartość jest przekazywana do sprintf
, który ją formatuje i umieszcza w innym tekście. Ten tekst jest przypisany bezpośrednio do specjalnej zmiennej $_
, która przechowuje nazwę pliku. Ponieważ rename
przetwarza pliki w kolejności, w jakiej są przekazywane jako argumenty, są odpowiednio ponumerowane.
Zarówno deklarują, jak i zwiększają zmienną licznika, i oba używają sprintf
zasadniczo w ten sam sposób, aby osadzić wartość tego licznika, wypełnionego zerami po lewej stronie, w innym tekście nowych nazw plików. (Informacje w obu odpowiedziach na temat wypełniania zerami i zmieniania szerokości dopełniania odnoszą się nawet do obu). Powodem, dla którego są tak podobne, jest to, że metoda w starszej odpowiedzi naprawdę robi właśnie to 1 , ale z dodatkowymi krokami, które są przydatne w przypadku wielu problemów, ale w rzeczywistości nie są w tym przypadku konieczne.
Dla porównania, oto jak wygląda drugie polecenie w tej odpowiedzi, jeśli zostało zmodyfikowane tak, aby używało stylu, którego użyłem tutaj (i by uzupełnić do szerokości 2, tak jak to zrobiłem tutaj, zamiast 3):
rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *
Część pomiędzy s/.+/
i /e
w tym poleceniu jest teraz taka sama jak wyrażenie, które przypisuję $_
(tj. Kod po prawej stronie =
operatora) w pierwszym poleceniu w tej odpowiedzi.
s/
napędu Próby dopasowania tekstu (rozszerzenie, że powłoka z rozszerzony *
i przekazywane jako parametry polecenie linii, gdy biegnące rename
) o zwykłej ekspresji , i dokonuje zmiany. /
jest używany jako separator do oddzielania różnych części s
wyrażenia. Pierwsza część .+
to wyrażenie regularne; dopasowuje dowolny 1 znak ( .
) i robi to raz lub więcej razy ( +
) . Ponieważ nazwy plików nigdy nie są puste - zawsze mają co najmniej jeden znak - jest to jeden ze sposobów dopasowania dowolnej 1 nazwy pliku.our $i; sprintf "AS%02d.txt", ++$i
. Spowoduje to utworzenie nowej nazwy pliku. Zazwyczaj używa się s/
do wytworzenia tekstu, który albo (a) zastępuje tekst pasujący tylko do części nazwy pliku, albo (b) w jakiś sposób bazuje na dopasowanym tekście (na przykład może użyć specjalnej zmiennej, $&
która rozwija się do mecz). W tym przypadku jednak dopasowany tekst nie jest w ogóle używany.our $i; sprintf "AS%02d.txt", ++$i
byłby używany jako nazwa pliku, a nie jako kod. Ale /e
flaga na końcu powoduje, że tekst jest traktowany jako kod źródłowy Perla i analizowany, i wykorzystuje wartość uzyskaną w ten sposób (w tym przypadku wartość zwracaną przez wbudowaną sprintf
funkcję Perla ) jako nową nazwę pliku.Chociaż uważam, że metoda, którą tutaj pokazałem, jest bardziej przejrzysta i prostsza w podejściu do tego problemu niż jakakolwiek metoda, s/
z której korzysta /e
, dobrze jest być świadomym tej techniki, ponieważ dobrze nadaje się do wielu innych problemów związanych ze zmianą nazwy pliku, w których wszystkie lub część oryginalnych nazw plików jest sprawdzana i / lub zachowywana. Polecam ten post na blogu autorstwa Oli (który również napisał tę odpowiedź ), który zawiera kilka takich przykładów.
1 Z technicznego punktu widzenia nie ma różnicy w zachowaniu się $_ =
poleceń i s/
/e
poleceń. W wyrażeniu regularnym .+
nie jest prawdą, że .
pasuje do dowolnego znaku, ponieważ nie pasuje do nowej linii . Prawdopodobnie nie powinieneś używać nazw plików z nowymi liniami, ale możesz, a czasami plik jest tak nazywany przypadkowo. Jeśli masz na to ochotę, skontrastuj wynik rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'
z rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'
. Aby .
dopasować nowy wiersz, użyj s
flagi, która znajduje się na końcu (z e
). Oznacza to, że pisz /se
na końcu zamiast /e
.
Załóżmy, że znajdują się pliki, których nazwę chcesz zmienić ~/Adir
, a są to jedyne pliki w tym folderze, a następnie:
n=0
for f in $( ls ~/Adir | sort ) ; do
n=$(( n+1 ))
mv -n "$f" "AS${n}.txt"
done
Ten skrypt sprawdzi każdy plik ~/Adir
i zmieni jego nazwę, AS1.txt, AS2.txt, ...
jeśli plik nie istnieje (nie nastąpi nadpisanie). Dlatego powinieneś upewnić się, że są to jedyne pliki w ~/Adir
. sort
Polecenie jest tylko w przypadku, gdy chcesz pliki zachować pierwotny porządek.
rename
nazwą Ubuntu jest prename. Może to być lepsze, ale możesz dodać instrukcje instalacji, aby uczynić tę odpowiedź bardziej wartościową.