Chcę zmienić nazwę plików, aby zmienić ich rozszerzenie, skutecznie starając się to osiągnąć
mv *.txt *.tsv
Ale robiąc to, otrzymuję:
* .tsv nie jest katalogiem
Wydaje mi się nieco dziwne, że pierwsze 10 hitów Google mvpowinno tak działać.
Chcę zmienić nazwę plików, aby zmienić ich rozszerzenie, skutecznie starając się to osiągnąć
mv *.txt *.tsv
Ale robiąc to, otrzymuję:
* .tsv nie jest katalogiem
Wydaje mi się nieco dziwne, że pierwsze 10 hitów Google mvpowinno tak działać.
Odpowiedzi:
Po wydaniu polecenia:
mv *.txt *.tsv
powłoka, załóżmy bash, rozwija symbole wieloznaczne, jeśli są jakieś pasujące pliki (w tym katalogi). Lista plików jest przekazywana do programu tutaj mv. Jeśli nie zostaną znalezione żadne dopasowania, wersja nierozwinięta jest przekazywana.
Znowu: powłoka rozszerza wzorce, a nie program.
Mnóstwo przykładów jest chyba najlepszym sposobem, więc zaczynamy:
$ ls
file1.txt file2.txt
$ mv *.txt *.tsv
Teraz w mvlinii dzieje się, że powłoka rozwija *.txtsię do pasujących plików. Ponieważ nie ma *.tsvplików, które nie zostaną zmienione.
mvPolecenie nazywa się z dwóch specjalnych argumentów :
argc: Liczba argumentów, w tym program.argv: Tablica argumentów, w tym program jako pierwszy wpis.W powyższym przykładzie byłoby to:
argc = 4
argv[0] = mv
argv[1] = file1.txt
argv[2] = file2.txt
argv[3] = *.tsv
mvKontrola programu, aby zobaczyć czy ostatni argument *.tsvjest katalogiem. Ponieważ tak nie jest, program nie może kontynuować pracy, ponieważ nie jest przeznaczony do łączenia plików. (Zazwyczaj przenieś wszystkie pliki do jednego.) Nie twórz katalogów według kaprysu.
W rezultacie przerywa działanie i zgłasza błąd:
mv: target ‘*.tsv’ is not a directory
Teraz, jeśli zamiast tego powiesz:
$ mv *1.txt *.tsv
mvPolecenie jest wykonywane z:
argc = 3
argv[0] = mv
argv[1] = file1.txt
argv[2] = *.tsv
Teraz ponownie mvsprawdź, czy *.tsvistnieje. W przeciwnym razie plik file1.txtzostanie przeniesiony do *.tsv. To znaczy: nazwa pliku zmienia się *.tsvna gwiazdkę i wszystko.
$ mv *1.txt *.tsv
‘file1.txt’ -> ‘*.tsv’
$ ls
file2.txt *.tsv
Jeśli zamiast tego powiedziałeś:
$ mkdir *.tsv
$ mv *.txt *.tsv
mvPolecenie jest wykonywane z:
argc = 3
argv[0] = mv
argv[1] = file1.txt
argv[1] = file2.txt
argv[2] = *.tsv
Ponieważ *.tsvteraz jest katalog, pliki są tam przenoszone.
Teraz: używając poleceń, takich jak some_command *.tsvkiedy rzeczywiście chcesz zachować symbol wieloznaczny, zawsze powinieneś go zacytować. Cytując, zapobiegasz rozszerzaniu symboli wieloznacznych, jeśli powinny być jakieś dopasowania. Powiedz np mkdir "*.tsv".
Rozszerzenie można wyświetlić jeszcze, jeśli wykonasz na przykład:
$ ls
file1.txt file2.txt
$ mkdir *.txt
mkdir: cannot create directory ‘file1.txt’: File exists
mkdir: cannot create directory ‘file2.txt’: File exists
Teraz: mvpolecenie może i działa na wielu plikach. Ale jeśli jest ich więcej niż dwa, ostatni musi być katalogiem docelowym. (Opcjonalnie możesz użyć tej -t TARGET_DIRopcji, przynajmniej dla GNU mv.)
Więc to jest OK:
$ ls -F
b1.tsv b2.tsv f1.txt f2.txt f3.txt foo/
$ mv *.txt *.tsv foo
Tutaj mvbędzie się nazywać z:
argc = 7
argv[0] = mv
argv[1] = b1.tsv
argv[2] = b2.tsv
argv[3] = f1.txt
argv[4] = f2.txt
argv[5] = f3.txt
argv[6] = foo
i wszystkie pliki trafiają do katalogu foo.
Co do twoich linków. Podałeś jeden (w komentarzu), w którym mvwcale nie wspomniano, ale rename. Jeśli masz więcej linków, które możesz udostępnić. Podobnie jak w przypadku stron podręcznika, w których twierdzisz, że jest to wyrażone.
Wiem, że to nie odpowiada na twoje pytanie, ale jeśli szukałeś innego sposobu zmiany nazwy plików w porównaniu do pętli obejścia, dlaczego nie użyć find? Używałem tego polecenia wiele razy, aby zastąpić rozszerzenia plików w dużych katalogach setkami tysięcy plików. Powinno to działać na każdym systemie zgodnym z POSIX:
find . -name "*.gappedPeak" -exec sh -c 'mv "$1" "${1%.gappedPeak}.bed"' _ {} \;
Podział poleceń:
'
.' => ścieżka wyszukiwania zaczynająca się od bieżącego katalogu oznaczonego przez '. „
-name=> ustaw szukaną nazwę dopasowania (w tym przypadku wszystkie pliki, które kończą się.gappedPeak)
-exec=> wykonaj następujące polecenie przy każdym dopasowaniu
sh -c=> 'exec' tworzy niezależne środowisko powłoki dla każdego dopasowania
mv "$1" "${1%.gappedPeak}.bed"=>mvpierwsza zmienna (oznaczona przez $ 1 ), która jest bieżącą nazwą pliku, do nowej nazwy. Tutaj wykonuję dopasowanie podciągu i usuwam; więc weź najpierw var, $ 1 i użyj,%aby usunąć.gappedPeakz ciągu..bedNa końcu po prostu skleja pozostałą zmienną, która jest teraz po prostu , z , tworząc nową nazwę pliku.test#.bedtest#.bedPodkreślenie jest symbolem zastępczym dla 0 USD
{}Otrzymuje każdego (*.gappedPeak) pliku znalezionego przezfindpolecenia i staje $ 1 doshkomendy.
\;oznacza koniec-execpolecenia. Możesz także użyć';'lub";".
Przykład:
[user@before]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.gappedPeak
[user@after]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.bed
file.abc-> blub.xyzw wielu katalogach podrzędnych:find . -name "file.abc" -exec sh -c 'mv "$1" "$(dirname $1)/blub.xyz"' _ {} \;
mv *.txt *.tsvnie działa; mvmoże zmienić nazwę tylko jednego pliku na raz. Albo źle zrozumiałeś wyjaśnienia, albo są w błędzie.
mmvi renamemoże zmieniać nazwy kilku plików jednocześnie. Ale istnieją dwie wersje, renamektóre są nazywane inaczej. Tutaj powinno być wiele pytań.
rename, a nie mv.
mv *.txt *.tsv mvnie (zwykle) nie widzi *.txtlub wyświetla *.tsvnazwy plików z rozszerzeniem powłoki. Liczba plików rozwijanych przez te symbole wieloznaczne byłaby „losowa”. Jedyną sytuacją, w której to działa, jest plik o nazwie, *.txtktórego nazwa zostanie zmieniona na (dosłownie) *.tsv(bez cytowania bashopcji nullglobnie można ustawić).
foo.txti jedną o nazwie będzie zastąpić istniejący plik ...baz.tsvmv *.txt *.tsv.tsv
Na przykład, jeśli masz asd.txti qwe.txtpliki w katalogu po uruchomieniu polecenia mv *.txt *.tsv, próbuje przenieść te dwa pliki do katalogu o nazwie *.tsv. Ponieważ nie ma takiego katalogu, pojawia się błąd.
rename(1)renamejest skryptem perla autorstwa Larry'ego Walla, twórcy perla. Wymaga wyrażenia regularnego Perla i działa na nazwie pliku.
rename 's/\.txt$/.tsv/' *.txt
Jeśli musisz zainstalować renamena Debian / Ubuntu, możesz to zrobić
sudo apt install rename
Inną opcją do rozważenia jest użycie:
cp -p *.txt *.tsv
rm -f *.txt
*.txtpliki *.tsv, zachowując ich atrybuty za pomocą -pflagi.*.txtmvktóra po prostu zmienia katalog / nazwę pliku bez przenoszenia plików, chyba że znajdują się na innej partycji.