Jest to prawdopodobnie bardzo proste, ale nie mogę tego rozgryźć. Mam taką strukturę katalogów (dir2 znajduje się w dir1):
/dir1
/dir2
|
--- file1
|
--- file2
Jaki jest najlepszy sposób „spłaszczenia” tej struktury dyrektora w taki sposób, aby uzyskać plik1 i plik2 w katalogu 1, a nie katalogu 2.
Odpowiedzi:
Możesz to zrobić za pomocą GNU
find
i GNUmv
:Zasadniczo sposób działa, jeśli
find
przechodzi przez całe drzewo katalogów i dla każdego pliku (-type f
), który nie znajduje się w katalogu najwyższego poziomu (-mindepth 2
), uruchamia a,mv
aby przenieść go do wybranego katalogu (-exec mv … +
).-t
Argumentmv
pozwala określić katalog docelowy pierwszy, który jest potrzebny, ponieważ+
forma-exec
umieszcza wszystkie lokalizacje źródłowe na końcu polecenia. Te-i
markimv
zapytać przed zastąpieniem żadnych duplikatów; możesz-f
je zastąpić bez pytania (lub-n
nie pytaj ani nie zastępuj).Jak zauważa Stephane Chazelas, powyższe działa tylko z narzędziami GNU (które są standardowe w Linuksie, ale nie w większości innych systemów). Poniższe jest nieco wolniejsze (ponieważ wywołuje
mv
wiele razy), ale o wiele bardziej uniwersalne:źródło
-exec +
tak, aby nie wykonywał dużej liczby procesówmv
mv
potrzebuje miejsca docelowego jako ostatniego argumentu, ale + miałby źródła jako ostatni argument. Znajdź nie zaakceptuje nawet składni, którą zmieniłeś na (find: missing argument to `-exec'
)mv
,-t
że możemy użyć, więc zmienię to na to.find
drukuje ukryte pliki (kropkowe). Głębokość zależy od katalogu, który przekazujesz do znalezienia.find ./dir -mindepth 2 -type f -exec mv -f '{}' ./dir ';'
przypadkuW Zsh:
**/
rekursywnie przegląda podkatalogi. Glob kwalifikator.
pasuje tylko zwykłe pliki, aD
gwarantuje, że pliki dot są włączone (domyślnie, pliki, których nazwa zaczyna się od.
są wyłączone z zamiennika mecze). Aby wyczyścić teraz puste katalogi, uruchomrmdir dir1/**/*(/Dod)
-/
ogranicza się do katalogów iod
najpierw porządkuje głębokość dopasowań, aby usunąć jedir1/dir2/dir3
wcześniejdir1/dir2
.Jeśli całkowita długość nazw plików jest bardzo duża, możesz napotkać ograniczenie długości linii poleceń. Zsh ma do pomocy poleceń wbudowanych
mv
irmdir
które nie są objęte tym ograniczeniem: uruchomzmodload zsh/files
je włączyć.Tylko z narzędziami POSIX:
lub (szybciej, ponieważ nie musi uruchamiać osobnego procesu dla każdego pliku)
źródło
Spróbuj to zrobić:
lub dla każdego pliku pasującego
file[0-9]*
w podkatalogu:Zobacz http://mywiki.wooledge.org/glob
źródło
{}
w moim prawdziwym problemie.Napisałem dwie funkcje, których możesz używać razem, możesz to zrobić, możesz ograniczyć poziom katalogu, dodając
-maxdepth $VAL
parametr.źródło
Rozwijając popularną odpowiedź na to pytanie, ponieważ miałem przypadek użycia do spłaszczenia katalogu zawierającego pliki o tej samej nazwie.
W tym przypadku przekazana opcja
-i
(--interactive
)mv
nie przyniosłaby pożądanego rezultatu spłaszczenia struktury katalogów i obsługi konfliktów nazw. Więc to jest po prostu zastąpione--backup=t
(równoważne--backup=numbered
). Więcej dokumentacji na temat opcji-b
(--backup
) jest dostępnych na https://www.gnu.org/software/coreutils/manual/coreutils.html#Backup-options .Wynikające z:
Co daje:
źródło
zarówno tar, jak i zip mają możliwość włączenia, a następnie usunięcia struktury katalogów, dzięki czemu mogłem szybko spłaszczyć zagnieżdżony katalog za pomocą
tar -cvf all.tar *
a następnie przeniesienie all.tar do nowej lokalizacji
tar -xvf all.tar --strip=4
źródło