2009-10-28 18:54:06 +0000 2009-10-28 18:54:06 +0000
134
134

Jak przenieść wszystkie pliki z bieżącego katalogu do górnego katalogu?

Jak przenieść wszystkie pliki z bieżącego katalogu do górnego katalogu w linuxie?

Próbowałem czegoś takiego jak mv *.*, ale to nie działa.

Odpowiedzi (11)

204
204
204
2009-10-28 19:01:58 +0000

Polecenie, którego szukasz to

mv * .[^.]* ..

lub (zobacz poniżej po więcej informacji):

(shopt -s dotglob; mv -- * ..)

Wyjaśnienie: polecenie mv przenosi pliki i katalogi. Ostatnim argumentem mv jest cel (w tym przypadku katalog o jeden krok “wyżej” w drzewie, ..). Argumenty przed nim to pliki i katalogi źródłowe. Gwiazdka (*) jest symbolem wieloznacznym, który pasuje do wszystkich plików, które nie zaczynają się od kropki. Pliki, które zaczynają się od kropki (dotfiles) są “ukryte”. Są one dopasowywane przy użyciu wzorca .[^.]* (zobacz edycję poniżej).

Zobacz stronę manpage, którą linkowałem po więcej informacji na temat mv.


Dlaczego .[^.]* zamiast .* ?

Jak słusznie zauważa Chris Johnsen : wzorzec .* pasuje również do . i ... Ponieważ nie chcesz (i nie możesz) ich przenieść, lepiej jest użyć wzorca, który pasuje do każdej nazwy pliku zaczynającej się od kropki z wyjątkiem tych dwóch. Wzorzec .[^.]* właśnie to robi: pasuje do każdej nazwy pliku (1) zaczynającej się od kropki (2), po której następuje znak, który nie jest kropką (3), po którym następuje zero lub więcej dowolnych znaków.

Jak Paggas wskazuje , musielibyśmy również dodać wzorzec .??* w celu dopasowania plików zaczynających się od dwóch kropek. Zobacz jego odpowiedź dla alternatywnego rozwiązania używającego find .

Arjan’s odpowiedź wspomina shopt w celu uniknięcia wszystkich tych problemów z dotfiles. Ale wtedy wciąż jest problem z plikami zaczynającymi się od myślnika. I wymaga to trzech poleceń. Mimo to, pomysł mi się podoba. Proponuję używać tego w ten sposób:

(shopt -s dotglob; mv -- * ..)

To wykonuje shopt w podpowłoce (a więc nie jest wymagane drugie wywołanie shopt) i używa --, aby pliki zaczynające się od myślnika nie były interpretowane jako argumenty do mv.

45
45
45
2009-10-28 20:19:07 +0000

Krótka odpowiedź: użyj

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

Długa odpowiedź:

Polecenie

mv * .* ..

nie będzie działać, ponieważ .* może pasować do . i ... Ale polecenie

mv * .[^.]* ..

również nie zadziała, ponieważ .[^.]* nie będzie pasować, np. do ..filename! Zamiast tego robię

mv * .[^.] .??* ..

, które będzie pasować do wszystkiego oprócz . i ... * dopasuje wszystko, co nie zaczyna się od ., .[^.] dopasuje wszystkie dwuznakowe nazwy plików zaczynające się od kropki z wyjątkiem .., a .??* dopasuje wszystkie nazwy plików zaczynające się od kropki z co najmniej 3 znakami.

Jeszcze lepiej, możesz użyć

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

co pozwoli uniknąć brzydkich globalnych hacków w mv * .[^.] .??* ..!

14
14
14
2009-10-28 20:52:27 +0000

Tak dla kompletności, można również powiedzieć powłoce Bash, aby uwzględniała ukryte pliki, używając shopt :

shopt -s dotglob
mv -- * ..
shopt -u dotglob
8
8
8
2011-08-02 20:46:48 +0000

W mv brakuje funkcjonalności przenoszenia ukrytych plików przy użyciu * - dlaczego więc nie użyć copy zamiast tego?

cp -rf . ..

rm -rf *

Nie ma potrzeby zagłębiać się w skomplikowane rozwiązania dotglobbingu i używania komend find.

7
7
7
2013-01-20 11:47:53 +0000
rsync -a --remove-source-files . ..

rsync jest niezwykle wydajnym narzędziem do kopiowania plików, zwykle używanym do wykonywania wydajnych przyrostowych zdalnych kopii zapasowych i kopii lustrzanych.

Powyższym poleceniem mówimy rsync, aby skopiował zawartość . do ..

Przełącznik -a umożliwia rekurencję do podkatalogów . i włącza kilka innych popularnych opcji.

Przełącznik --remove-source-files mówi rsync, aby usunął pliki źródłowe po udanej kopii, tj. sprawia, że rsync zachowuje się podobnie do polecenia mv.

2
2
2
2011-08-12 08:12:49 +0000

Ta zminimalizowana komenda działa na większości nowoczesnych powłok:

\mv -- {,.{[^.],??}}* ..

Inaczej mówiąc jest to rozwiązanie przenośne:

\mv -- * .[^.] .??* ..

Features:

  1. \ Zapobiega niepożądanym zmianom mv przez aliasy.

  2. – zapobiega interpretowaniu nazw plików zawierających myślniki (-xyz) jako argumentów wiersza poleceń.

  3. .[^.] pasuje do wszystkich dwuznakowych nazw plików zaczynających się od . z wyjątkiem …

  4. .??* pasuje do wszystkich innych nazw plików o długości trzech znaków lub dłuższych.

Naiwne implementacje:

  1. Następujące pomija ukryte nazwy plików UNIX, te które zaczynają się od . (.bashrc).

  2. Poniższe pasuje do .., który rekursywnie próbuje przenieść każdy katalog ostatecznie aż do / do .. bieżącego katalogu roboczego ($PWD lub pwd). Nigdy nie używaj.

2
2
2
2009-10-28 18:59:46 +0000

Ostatecznie próba mv . nie powiedzie się, ponieważ mv nie będzie w stanie odłączyć katalogu, w którym obecnie się znajdujesz. Możesz mv * .., aby przenieść pliki w cwd.

2
2
2
2013-10-22 22:24:11 +0000

Bardziej poprawne jest użycie wzorca * .[!.] .??* niż * .[^.] .??*, ponieważ ten pierwszy będzie działał także ze starszymi powłokami, takimi jak ksh88: -- pasuje do wszystkich dwuznakowych nazw plików, które zaczynają się od - - * pasuje do wszystkich trzyznakowych nazw plików (lub dłuższych), które zaczynają się od .

W ksh88, wzorzec nazwy pliku . w rzeczywistości dopasuje nazwy plików .[!.] (który zawsze istnieje) i . (który prawdopodobnie nie istnieje), dając efekt przeciwny do pożądanego.

2
2
2
2009-10-28 19:47:28 +0000
mv * .??* ../.

* pobiera wszystkie pliki bez kropek. .??* dostaje wszystkie pliki o długości co najmniej trzech bajtów, co działa dla wszystkich legalnych plików. Wszystko, co pozostało, prawdopodobnie i tak chcesz rm zamiast mv.

The ../. nie oferuje żadnych bezpośrednich korzyści w porównaniu do .., ale podczas wykonywania move-to-directory jest to bardzo dobry nawyk, ponieważ nie powiedzie się, tak jak chcesz, jeśli coś jest nie tak ze ścieżką. Na przykład, mv xyz bletch, gdzie myślisz, że bletch jest katalogiem, może być bardziej pewne z mv xyz bletch/..

0
0
0
2014-05-12 23:08:11 +0000

Find i grep również działają. Tego typu struktura może być pomocna, jeśli chcesz wybierać pliki według bardziej skomplikowanych kryteriów, modyfikując find i egrep.

find -maxdepth 1 | egrep '^./.' # Returns all files

mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..
0
0
0
2014-08-06 16:37:16 +0000

Myślę, że najprostszym rozwiązaniem dla przeniesienia wszystkich plików do ich macierzystego dir. byłoby

mv "`ls`" ../

lub, jeśli istnieją ukryte pliki/katalogi

użyj:

mv "`ls -a`" ../ 2>/dev/null

Również, powiedzmy, że chcesz przenieść zawartość jakiegoś folderu do jednego z jego wewnętrznych folderów tony(powiedzmy)

użyj:

mv "`ls -a`" /tony 2>/dev/null

Uwaga:

"`ls -a`"

Aby przenieść pliki, które mają w sobie spacje.

2>/dev/null

Służy do wyciszenia ostrzeżeń/błędów, ponieważ ls -a wydrukuje również foldery . i .. i nie można ich przenieść ani skopiować. Więc dla tych folderów będzie wyświetlał błąd (jeśli nie użyjemy 2:2/dev/null), że nie może ich przenieść, a reszta zostanie przeniesiona całkiem wygodnie.

Najlepiej unikać ls -a jeśli nie ma żadnych ukrytych plików i po prostu użyć ls.