Jak rekurencyjnie przenieść wszystkie pliki (w tym ukryte) z podfolderu do folderu nadrzędnego w * nix?

14

To trochę kłopotliwe pytanie, ale muszę przyznać, że tak późno w mojej karierze wciąż mam pytania dotyczące polecenia mv.

Często mam ten problem: muszę rekursywnie przenosić wszystkie pliki o jeden poziom wyżej. Powiedzmy, że mam folder foo i pasek folderów w nim. Pasek zawiera bałagan plików i folderów, w tym plików i folderów kropkowych. Jak przenieść wszystko na pasku do poziomu Foo?

Jeśli foo jest puste, po prostu przesuwam pasek o jeden poziom wyżej, usuwam foo i zmieniam nazwę paska na foo. Częściowym problemem jest to, że nie mogę zrozumieć, co to jest symbol wieloznaczny mv dla „wszystkiego łącznie z kropkami”. Częścią tego pytania jest to - czy jest dogłębna dyskusja na temat symboli wieloznacznych, które gdzieś używają poleceń cp i mv (przeglądanie to przynosi tylko bardzo podstawowe samouczki).

Deadprogrammer
źródło

Odpowiedzi:

19

W Bash (i niektórych innych) możesz użyć rozwijania nawiasów, aby osiągnąć to w jednym wierszu:

mv bar/{,.}* .

Przecinek oddziela null i kropkę, więc mvpolecenie widzi nazwy plików pasujące do *i.*

Wstrzymano do odwołania.
źródło
ta próba przeniesienia również „..” kończy się niepowodzeniem, komunikat „zasób jest zajęty”. Mimo to działa.
Xananax,
3
Sugerowany przez anonimowego użytkownika:To eliminate the error caused by also matching "." and "..", use this command: mv bar/{,.[!.],..?}* .
HopelessN00b
2

Najłatwiej to zrobić za pomocą dwóch poleceń, ponieważ * nie pasuje. Cokolwiek

cd /foo
mv bar/* ./
mv bar/.??* ./

Nie chcesz używać paska /.*, którego dowiedziałem się podczas popełnienia tego błędu:

rm -rf ./.* 

To jest ZŁA RZECZ. Czy ktoś chce zgadnąć, dlaczego? ;-)

Matt Simmons
źródło
Nie sądzę, że Bash lub Zsh rozwija się .*do .i ... Zsh przynajmniej nie dla mnie.
Mikael S
Mikael: Mogę obiecać, że bash to zrobi (a przynajmniej tak zrobił), ponieważ musiałem odzyskać katalogi użytkowników, które wymazałem, robiąc to właśnie
Matt Simmons,
2

Pierwszą rzeczą, którą należy wiedzieć o globowaniu - jest wykonywana przez powłokę, a nie polecenie. Sprawdź stronę podręcznika swojej powłoki, aby poznać wszystkie szczegóły.

Jeff Leyser
źródło
2

Ten pobiera wszystkie pliki z podfolderów i przenosi je do bieżącego katalogu

find . -type f -exec mv -iv \{} . \;

Jeśli chcesz posiadać pliki o tej samej nazwie, użyj

yes y | find . -type f -exec mv -iv \{} . \;
michelek
źródło
1

mv .??* *zajmie się wszystkim oprócz kropki i pojedynczego znaku. Jeśli jest to typowe w Twojej sytuacji, możesz dodać .[a-zA-Z0-9]*. Że będzie nadal pozostawiają pliki o nazwach takich jak .;, .^i .^I(TAB). Jeśli musisz obsłużyć wszystko, musisz być nieco bardziej złożony.

mv .. `ls -f | egrep -v '^.$|^..$'
mpez0
źródło
0

Jeśli masz strukturę katalogów /foo/bar/i chcesz przenieść wszystkie pliki w ramach barjednego kroku powyżej, przejdź do barkatalogu i wpisz następujące polecenie:

find . -depth -print0 | cpio --null -pvd ../

Generalnie myślę, że cpio(1)lepiej nadaje się do tego rodzaju zadań. Możesz sprawdzić szczegółową dokumentację, wydając info cpiow swojej powłoce.

fim
źródło