Jak przenieść wszystkie pliki z katalogu (w tym te ukryte) do innego katalogu?
Na przykład, jeśli mam folder „Foo” z plikami „.hidden” i „notHidden”, jak przenieść oba pliki do katalogu o nazwie „Bar”? Poniższe nie działa, ponieważ plik „.hidden” pozostaje w „Foo”.
mv Foo/* Bar/
Spróbuj sam.
mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
Odpowiedzi:
Zsh
lub
(Pomiń,
(N)
jeśli wiesz, że katalog nie jest pusty).Grzmotnąć
Ksh93
Jeśli wiesz, że katalog nie jest pusty:
Standardowy (POSIX) sh
Jeśli chcesz, aby
mv
polecenie zwróciło status błędu, nawet jeśli się powiodło, jest to o wiele prostsze:GNU find i GNU mv
Znalezienie standardowe
Jeśli nie przeszkadza ci przejście do katalogu źródłowego:
Oto więcej szczegółów na temat kontrolowania, czy pliki kropek są dopasowane w bash, ksh93 i zsh.
Grzmotnąć
Ustaw
dotglob
opcję .Istnieje również bardziej elastyczna
GLOBIGNORE
zmienna , którą można ustawić na listę wzorców symboli wieloznacznych oddzielonych dwukropkami, które mają być ignorowane. Jeśli nie jest ustawiony (ustawienie domyślne), powłoka zachowuje się tak, jakby wartość była pusta, jeślidotglob
jest ustawiona, i tak, jakby wartość była,.*
jeśli opcja była nieaktywna. Zobacz Rozszerzenie nazwy pliku w instrukcji. Wszechobecna katalogów.
i..
zawsze są pominięte, chyba że.
jest dopasowany dosłownie przez wzorzec.Ksh93
Ustaw
FIGNORE
zmienną . Jeśli nieustawione (ustawienie domyślne), powłoka zachowuje się tak, jakby była to wartość.*
. Aby zignorować.
i..
, należy je jednoznacznie dopasować (instrukcja w ksh 93s + 2008-01-31 stwierdza, że.
i..
zawsze są ignorowane, ale nie opisuje to poprawnie faktycznego zachowania).Możesz dodać pliki kropek do wzorca , dopasowując je jawnie.
Aby rozszerzenie było puste, jeśli katalog jest pusty, użyj
N
opcji dopasowania wzorca:~(N)@(*|.[^.]*|..?*)
lub~(N:*|.[^.]*|..?*)
.Zsh
Ustaw
dot_glob
opcję ..
i..
nigdy nie są dopasowywane, nawet jeśli wzorzec.
wyraźnie pasuje do wiodącego .Możesz dołączyć pliki kropek według określonego wzorca z
D
kwalifikatorem glob .Dodaj
N
kwalifikator glob aby ekspansję wyjdzie pusty w pustym katalogu:*(DN)
.Uwaga: można uzyskać nazwy pliku wyników dylatacyjnych w różnych zleceń (np
none
następnie.one
następuje..two
) w oparciu o ustawieniach tychLC_COLLATE
,LC_ALL
orazLANG
zmiennych.źródło
nullglob
? Bardziej sensowne byłoby przerwaniemv
polecenia (jak fish, csh / tcsh, zsh (bez(N)
) do lub bash z failglob) niż uruchomieniemv /Bar/
polecenia, które nie ma sensu..
i..
nigdy nie są dopasowane (podobnie jak w innych sensownych muszli jak zsh, ryby, pdksh i pochodnych), nawet jeśli włączyć dotglob wycofać później. (GLOBIGNORE=:; shopt -u dotglob; echo .*
nie wyjdzie.
i..
). Ustawienie GLOBIGNORE do.:..
lub.
czy:
mają taki sam efekt.ksh93
zawsze ignoruje.
i..
wydaje się, że został złamany pomiędzyksh93k+
(gdzie działał) aksh93m
(gdzie już nie działa). Zauważ, że jest źle,ksh93
ponieważ pobiera wartość FIGNORE ze środowiska, więcFIGNORE='!(..)'
na przykład env var może wywołać spustoszenie.Od
man bash
źródło
mv
narzekania, że ten plik o nazwieFoo/*
nie istnieje. Co ciekawe, jeśliFoo
można przeszukiwać, ale nie można go odczytać, a tam jest wywołany plik,*
nie pojawi się błąd, ten plik zostanie przeniesiony, ale nie pozostałe w katalogu.bash
posiadafailglob
opcję tak zachowuje się bardziej jakzsh
,fish
lubcsh
/tcsh
i przerwać polecenie z błędem gdy glob nie może być rozszerzona zamiast tego fałszywego zachowania pozostawiając glob jak jest.Prostym sposobem na to
bash
jestAle spowoduje to także przeniesienie katalogów.
Jeśli chcesz przenieść wszystkie pliki, w tym ukryte, ale nie chcesz przenosić żadnego katalogu, możesz użyć pętli for i przetestować.
for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;
źródło
Jednym ze sposobów jest użycie
find
:-type f
Ogranicza polecenie Znajdź, aby znaleźć pliki. Należy przeprowadzać dochodzenia w sprawie-type
,-maxdepth
, i-mindepth
opcjefind
, aby dostosować polecenia uwagę podkatalogów. Znajdź ma długą, ale bardzo pomocną stronę podręcznika .źródło
Foo/
, a nie podkatalogi i inne pliki.Spróbuj wykonać polecenie kopiowania
cp
:cp -r
oznacza kopiowanie rekurencyjne, więc wszystkie foldery i pliki zostaną skopiowane.Możesz użyć polecenia
rm
remove, aby usunąć folder:Zobacz więcej: przenieś wszystkie pliki z katalogu do innego .
źródło
Rsync to kolejna opcja:
Działa to, ponieważ w rsync ukośnik końcowy ma znaczenie,
sourcedirectory/
odnosi się do zawartości katalogu, podczas gdysourcedirectory
odnosi się do samego katalogu.Wadą tej metody jest to, że rsync wyczyści pliki dopiero po przeniesieniu, a nie katalog. Pozostaje ci więc puste drzewo katalogów. Aby obejść ten problem, zobacz:
Przenosić pliki i usuwać katalogi za pomocą rsync?
Chociaż może to nie być optymalne dla operacji przenoszenia, może być niezwykle przydatne w przypadku operacji kopiowania.
źródło
Odpowiedz na bash / fish
Oto sposób na zrobienie tego za pomocą symboli wieloznacznych:
.[!.]* ..?*
dopasuje wszystkie ukryte pliki oprócz.
i..
.[!.]* ..?* *
dopasuje wszystkie pliki (ukryte lub nie) oprócz.
i..
Aby odpowiedzieć na konkretny przykład tego pytania, potrzebujesz
cd foo && mv .[!.]* ..?* * ../bar
Wyjaśnienie
.[!.]*
dopasowuje nazwy plików zaczynające się od jednej kropki, po której następuje dowolny znak oprócz kropki, po której opcjonalnie następuje dowolny ciąg. Jest to wystarczająco blisko, ale brakuje plików zaczynających się od dwóch kropek, takich jak..foo
. Aby dołączyć takie pliki, dodajemy..?*
pasujące nazwy plików zaczynające się od dwóch kropek, po których następuje dowolny znak, opcjonalnie po nim dowolny ciąg.Test
Możesz przetestować te symbole wieloznaczne za pomocą poniższych poleceń. Próbowałem z powodzeniem pod batem i rybą. Zawodzą pod sh, zsh, xonsh.
źródło
Możesz także znaleźć i grep z cudzysłowami wstecznymi, aby wybrać pliki dla polecenia przenoszenia. Przekaż je do mv.
To znaczy dla ukrytych plików
Więc
Przenosi tylko wybrane ukryte pliki do
Bar
:Przenosi wszystkie pliki w Foo do Baru od „.” w poleceniu egrep działa jak symbol wieloznaczny bez nawiasów kwadratowych.
^
Charakter zapewnia rozpoczyna mecz od początku linii.Niektóre szczegóły
egrep
dopasowania wzoru można znaleźć tutaj .Korzystanie z
maxdepth 1
zatrzymania wyszukiwania przed przejściem do podkatalogów.źródło
Inspirowany tą odpowiedzią :
Bez kopiowania plików ...
Ostrzeżenia:
--link-dest
ścieżka musi być bezwzględna lub względna w stosunku do DESTINATION (Bar
w przykładzie)Musisz wstawić
/
po ŹRÓDŁO (Foo/
w przykładzie), w przeciwnym razie skopiuje folder SOURCE zamiast jego zawartości.źródło
Uważam, że działa to dobrze w przypadku bash i nie trzeba zmieniać opcji powłoki
EDYTOWAĆ:
Tak więc, jak stwierdził G-man, moja pierwotna odpowiedź nie jest zgodna z posixem i jest prawie taka sama jak powyższa odpowiedź ndemou z jedną zmianą, która polega na użyciu rozwijania nawiasów klamrowych do tworzenia list ciągów znaków, które są następnie przetwarzane. Oznacza to po prostu, że nie musisz
cd
wchodzić do katalogu źródłowego. Naprawdę niezbyt duża zmiana, ale jest inna.przykład: załóżmy, że masz już następujący układ.
W pierwotnym pytaniu wspomniano tylko o ukrytych plikach z pojedynczą kropką, ale powiedzmy, że niektóre mają dwa lub więcej kropek na początku nazwy. Możesz po prostu dodać dodatkowe wyrażenie do nawiasów klamrowych. Następnie możemy wykonać
Zostanie to rozszerzone do następującego:
Powinieneś teraz zobaczyć wszystkie pliki znajdujące się w destdir :
Możesz robić całkiem fajne rzeczy z szelkami w bashu z jeszcze większą liczbą dodatków w 4.x. Sprawdź bash-hakerów, aby uzyskać jakieś fajne przykłady.
źródło
..
, i (2) aby być zgodnym z POSIX , powinieneś użyć!
zamiast^
; tj{*,.[!.]*}
.cd
wchodzić do katalogu źródłowego, aby działać na plikach lub zapisywać te same ścieżki plików w kółko, aby wyrazić ścieżki do wszystkich plików. Niedługo zaktualizuję przykład, aby dać czytelnikom lepszy obraz tego, o czym mówię.W przypadku minimalnej dystrybucji Linuksa powinny działać następujące. Najpierw wykonaj podstawowy ruch wszystkich (co spowoduje pominięcie ukrytych plików). Następnie przenieść wszystkie pliki ukryte (w tym
.
i..
które nie faktycznie być przeniesiony).Uwagi: Jeśli nie ma widocznej treści, pierwsze polecenie wyświetli komunikat o błędzie. Drugie polecenie zawsze spowoduje błąd informujący, że nie można go przenieść
.
i..
. W związku z tym po prostu potokuj błędy w/dev/null
(jak pokazano).Jeśli potrzebujesz tego jako jednowarstwowego, po prostu połącz je z średnikiem:
źródło