Jaka jest różnica między „zmień nazwę” a „mv”?

12

Nie jest to dla mnie całkowicie jasne, ale jaka jest różnica między mvi rename(od util-linux-ng 2.17.2as /usr/bin/rename)? Czy istnieją zalety jednego nad drugim poza renameakceptowaniem wyrażeń regularnych, a mvnie? Wierzę, że renamemoże obsługiwać wiele nazw plików jednocześnie, podczas mvgdy nie robi tego.

Nie mogłem znaleźć wyraźnego wskazania na ich manstronach, co jeszcze je wyróżnia, ani przez własne dochodzenie.

Urda
źródło
2
Upewnijmy się, że mówimy o tych samych rzeczach; jakie są wyjścia z type -a renamea rename --version?
Jeff Schaller
@JeffSchaller To z mojej strony ciekawość, ale na jednej z moich * nix maszyn mam rename is /usr/bin/renamei rename (util-linux-ng 2.17.2)odpowiednio.
Urda
6
Istnieje kilka różnych nazw i może to być alias / funkcja / skrypt, więc chciałem się tylko upewnić, że wiemy, co to jest. Dziękuję Ci! Edytuj te dane wyjściowe w swoim pytaniu.
Jeff Schaller
@JeffSchaller nie martw się, w rzeczywistości ten link był właśnie tym, który właśnie odkryłem, który pokazał mi, że renamemoże oznaczać różne rzeczy w różnych dystrybucjach.
Urda
5
Wygląda na to, że twoje pytanie zawiera odpowiedź. „Jaka jest różnica między odrzutowcem a trójkołowem, poza tym, że odrzutowiec może latać i może lecieć kilka tysięcy razy szybciej?” :-) ⁠
G-Man Says 'Reinstate Monica'

Odpowiedzi:

21

Jest to w zasadzie to, co jest napisane na wieczku, dla obu.

mvto standardowe narzędzie do przenoszenia jednego lub więcej plików do danego celu. Można go użyć do zmiany nazwy pliku, jeśli istnieje tylko jeden plik do przeniesienia. Jeśli jest ich kilka, mvdziała tylko wtedy, gdy celem jest katalog i przenosi tam pliki.

Więc mv foo baralbo przeniesie plik foodo katalogu bar(jeśli istnieje), albo zmieni nazwę foona bar(jeśli barnie istnieje lub nie jest katalogiem). mv foo1 foo2 barpo prostu przeniesie oba pliki do katalogu barlub narzekam, jeśli barnie jest to katalog.

mvwywoła rename()funkcję biblioteki C, aby przenieść pliki, a jeśli to nie zadziała (zostaną przeniesione do innego systemu plików), skopiuje pliki i usunie oryginały.

Jeśli wszystko, co masz, to mvi chcesz zmienić nazwę wielu plików, będziesz musiał użyć pętli powłoki. Istnieje wiele pytań, na które tutaj na miejscu, patrz na przykład to , to , i inne .


Z drugiej strony różne renamenarzędzia zmieniają nazwy plików indywidualnie.

Wspomniany renamez util-linux dokonuje prostego podstawienia łańcucha, np. rename foo bar *Zmieniłby się foobarna barbari asdffoona asdfbar. To nie nie biorą jednak wyrażenia regularnego!

Narzędzie zmiany nazwy Perla ( lub różne jego instancje ) pobiera wyrażenie Perla w celu transformacji nazw plików. Najprawdopodobniej użyjesz polecenia, w którym wzorzec jest wyrażeniem regularnym.s/pattern/replacement/

Zarówno zmiana nazwy util-linux, jak i zmiana nazwy Perla mogą być używane do przenoszenia plików do innego katalogu w tym samym czasie, poprzez dokonanie odpowiednich zmian w nazwie pliku, ale jest to trochę niewygodne. Podobnie jak wywoływanie rename()plików, więc przenoszenie się z jednego systemu plików do drugiego nie działa.

Jak na renameto masz, może to zależeć od twojej dystrybucji i / lub tego, co zainstalowałeś. Większość z nich obsługuje rename --version, więc użyj tego, aby określić, który z nich masz.

ilkkachu
źródło
Nie tylko „wyrażenie regularne”, ale funkcjonuje w razie potrzeby
Gilles Quenot
@GillesQuenot, cóż, tak, możesz zrobić np. rename '$_=lc' *Małe nazwy plików. Ale myślę, że najczęstszym przypadkiem jest użycie s///(o którym wspomniałem), a część wzorcowa to wyrażenie regularne; Nie sądzę, żebyś mógł użyć tam funkcji. Możesz to jednak zrobić w części zamiennej.
ilkkachu
@MyWrathAcademia, Ten pierwszy przykład na stronie man działa dla mnie (po prostu robi to inaczej niż drugi). Powodem, dla którego podłączyłem do stron podręcznika Debiana, jest to, że przynajmniej tam wyjaśniono, że strona podręcznika dla rename.uljest i będzie dla wersji util-linux, a nie dla żadnej innej.
ilkkachu
@ilkkachu, czy masz coś przeciwko dodaniu wyjaśnienia do tego pierwszego przykładu w odpowiedzi lub w komentarzu. Różni się od przykładu, man renamewięc dobrze byłoby wiedzieć, jak rozumiesz przykład z Debiana
MyWrathAcademia
@MyWrathAcademia, założyłem, że masz na myśli rename foo foo0 foo?; rename foo foo0 foo??przykład, ponieważ była to jedyna różnica między tymi dwoma stronami podręcznika , które widziałem. Ta para poleceń działa, ponieważ pierwsza dodaje zero do nazw każdej jednocyfrowej nazwy pliku, a następnie druga dodaje (kolejne) zero do każdej dwucyfrowej nazwy pliku. Ten drugi zestaw zawiera pliki, których nazwa została zmieniona przez pierwsze polecenie. Używanie rename foo foo00 foo?pierwszego polecenia również działa, po prostu dodaje dwa zera za jednym razem.
ilkkachu
2

mvpo prostu zmienia nazwę pliku (można go również przenieść do innego systemu plików lub ścieżki). Nadajesz mu starą nazwę i nową nazwę, i zmienia plik na nową nazwę lub lokalizację. renamesłuży do wprowadzania zbiorczych zmian nazewnictwa. Załóżmy, że miał tysiąc plików, foo000.logdzięki foo999.logi chcesz zmienić ich bar000.log? Poprzez bar999.log. Ze mvtrzeba by zrobić mv foo000.log bar000.log, mv foo001 bar001.logitd albo napisać skrypt. Po renameprostu zrób to rename foo bar foo*.logi voila, tysiąc plików zmienia się w jednej chwili! Całkiem fajne. Sprawdź man renamestronę ponownie, aby uzyskać szczegółowe informacje.

eewanco
źródło
2

mv

Jest to podstawowy wiersz poleceń zaprojektowany, aby zrobić jedną rzecz i zrobić to dobrze (filozofia Uniksa): przenieś plik (i) lub reżyser (y) .

Możesz hakować STDOUTi STDIN¹, aby modyfikować w locie ciąg docelowy, ale to nie jest mądry hack

zmień nazwę (Perl's)

ostrzeżenie Istnieją inne narzędzia o tej samej nazwie, które mogą lub nie mogą tego zrobić, więc bądź ostrożny.

Kiedy ludzie mówią rename, myślimy o tym, a nie o tym ELF, mniej potężnym (magia?).

To nie jest podstawowe, to Perl. Możesz przekazać niektóre funkcje Perla w środku, i jest to niezwykle potężne.

Rozważ ten przykład:

Chcesz zmienić nazwę wielu plików takich jak

foobar_1.txt
foobar_2.txt
foobar_3.txt

Możesz dodawać zera do cyfr w sprintf()następujący sposób (używając regex, heh, to Perl: D):

rename 's/(\d+)/sprintf("%04d", $1)/e' foobar_*.txt

Teraz masz :

foobar_0001.txt
foobar_0002.txt
foobar_0003.txt

To nie jest naprawdę podstawowe polecenie, prawda?

nie jest tak naprawdę zaprojektowana do przenoszenia katalogów , ale może to zrobić:

$ mkdir -p /tmp/foo/bar/base
$ touch /tmp/foo/bar/base/file
$ rename 's!/tmp/foo/bar/base/file!/tmp/file!' /tmp/foo/bar/base/file

Przeniesiony plik

/tmp/file

¹ trochę kodu, który widzimy na *.stackexchange.*stronach internetowych

wprowadź opis zdjęcia tutaj

for FILE in `ls *.txt`
do
    mv ${FILE} `echo ${FILE} | sed 's/anything_ugly/anything_still_ugly/'`
done

To nie jest właściwa droga , to zwykły buggy, po prostu, aby wyjaśnić, dlaczego używać właściwego narzędzia we właściwym momencie

Gilles Quenot
źródło
+1 za sprintfing przy zmianie nazwy
Archemar
-1

mv przenosi lub zmienia nazwy plików i katalogów i tworzy ich kopie zapasowe; zmiana nazwy zmienia tylko nazwy plików.

mv ma więcej możliwości i opcji. Spójrz na przełączniki na stronach podręcznika dla każdego, aby zobaczyć różnice w możliwościach. Rzućmy okiem za pomocą man w Ubuntu 18.04LTS (przebieg może się różnić w zależności od wersji każdego pakietu):

opcje mv (pomijając pomoc i wersję)

   --backup[=CONTROL]  
          make a backup of each existing destination file  

   -b     like --backup but does not accept an argument  

   -f, --force  
          do not prompt before overwriting  

   -i, --interactive  
          prompt before overwrite  

   -n, --no-clobber  
          do not overwrite an existing file  

  If you specify more than one of -i, -f, -n, only the final one takes effect.  

   --strip-trailing-slashes  
          remove any trailing slashes from each SOURCE argument  

   -S, --suffix=SUFFIX  
          override the usual backup suffix  

   -t, --target-directory=DIRECTORY  
          move all SOURCE arguments into DIRECTORY  

   -T, --no-target-directory  
          treat DEST as a normal file  

   -u, --update  
          move only when the SOURCE file is newer than the destination file or when the destination file is missing  

   -v, --verbose  
          explain what is being done  

   -Z, --context  
          set SELinux security context of destination file to default type  

zmień nazwę opcji (pomijając pomoc i wersję)

   -s, --symlink   
          Do not rename a symlink but its target.  

   -v, --verbose  
          Show which files where renamed, if any.  

   -n, --no-act  
          Do not make any changes.  

   -o, --no-overwrite  
          Do not overwrite existing files.            
K7AAY
źródło
3
Zdefiniuj „mocniejszy”. Czy mv obsługuje wyrażenia regularne, takie jak zmiana nazwy?
Gilles Quenot
Jak stwierdził pytający, nie.
K7AAY
2
Wow, co za kłótnia
Gilles Quenot
1
Udzielanie kredytu tam, gdzie jest on należny.
K7AAY