Mam kilka plików .zip w kilku katalogach:
Fol1/Fol2
Fol3
Fol4/Fol5
Jak mam przenieść je wszystkie do wspólnego folderu podstawowego?
Mam kilka plików .zip w kilku katalogach:
Fol1/Fol2
Fol3
Fol4/Fol5
Jak mam przenieść je wszystkie do wspólnego folderu podstawowego?
Odpowiedzi:
Przejdź do katalogu najwyższego poziomu drzewa zawierającego pliki zip ( cd …
), a następnie uruchom
mv **/*.zip /path/to/single/target/directory
Działa to natychmiast po wyjęciu z pudełka. Jeśli twoja powłoka jest bash, musisz shopt -s globstar
najpierw uruchomić (możesz i powinieneś umieścić to polecenie w swoim ~/.bashrc
). Jeśli twoją powłoką jest ksh, musisz uruchomić set -o globstar
najpierw (włóż ją do swojego ~/.kshrc
).
Alternatywnie, użyj find
, który działa wszędzie bez specjalnego przygotowania, ale jest bardziej skomplikowany:
find . -name '*.zip' -exec mv {} /path/to/single/target/directory \;
Jeśli chcesz później usunąć puste katalogi, w zsh:
rmdir **/*(/^Fod)
W bash lub ksh:
rmdir **/*/
i powtarzaj tak długo, jak są puste katalogi do usunięcia. Alternatywnie, w dowolnej powłoce
find . -depth -type d -empty -exec rmdir {} \;
find
polecenie powyżej działało w bashu, ale musiało się zmienić na find . -name
etc, aby działało.
.
jest domyślny dla GNU find, ale nie dla innych, dodałem go jawnie.
Jeśli używasz bash w wersji 4 lub wyższej lub zsh , możesz także użyć globowania rekurencyjnego:
mv **/*.zip /path/to/move/zip/files/to
To przeniesie TYLKO pliki, a nie ich ścieżki względne, więc mogą wystąpić kolizje.
Ten jest bezpieczny przy przenoszeniu danych i bezbłędnie, co obsługuje większość dystrybucji niezależnie od wersji. To polecenie skanuje podkatalogi, a następnie przenosi lub kopiuje do nowego katalogu docelowego.
find . -name *.flac -exec mv '{}' "./flac/" ";"
*.flac
na coś takiego jak *.zip
w twoim przypadku. Lub *.doc
tylko każde rozszerzenie działa.mv
jest poleceniem do przenoszenia plików, lub możesz użyć cp
do skopiowania danych zamiast przenoszenia../flac/
to katalog docelowy, do którego chcę przenieść wszystkie pliki FLAC. Możesz także nadać mu pełną ścieżkę/home/myid/flac/
Pełny przykład. (w tym przypadku istnieje wiele podkatalogów z nazwą wykonawcy muzyki na, /home/myid/Music/
a pliki FLAC znajdują się na różnych poziomach podkatalogów. Ponieważ nie potrzebuję folderów wykonawców, ale chcę mieć wszystkie pliki FLAC w jednym katalogu na/home/myid/Music/flac/
cd /home/myid/Music
mkdir flac
find . -name *.flac -exec mv '{}' "./flac/" ";"
cd flac
ls
Następnie wyświetli wszystkie pliki FLAC.
;
zrobić?
Jako hack bash możesz wykorzystać moc tar
:
(cd origin/;find . -exec file --mime-type "{}" \;|grep "application/zip"|cut -d ':' -f 1|xargs tar cf -)|(cd target/; tar xf -) && rm -fr origin/
Ma to tę zaletę, że nie zależy od rozszerzeń plików, ponieważ używa file
polecenia do wyboru plików do przeniesienia i zachowuje strukturę katalogów, ale nie działa ze ścieżkami zawierającymi spacje.
Ostatnim rm
jest tylko usunięcie oryginalnych plików (ponieważ @InquilineKea mówi, że nie dba o oryginalny folder w komentarzu).
Oczywiście jest to szczególnie odpowiednie, jeśli folder źródłowy / docelowy / znajdują się na różnych dyskach. W przeciwnym razie inne proponowane rozwiązania są bardziej wydajne (nawet jeśli opierają się na konwencjach nazewnictwa, a nie na file
treści).
Zakładając, że masz wersje GNU find i mv, poniższe będą bardziej wydajne niż istniejące odpowiedzi oparte na znalezieniu:
find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +
Użycie a +
na końcu find -exec oznacza, że lista plików zostanie przekazana do komendy mv, zamiast wykonywania jednej komendy mv na znaleziony plik. Ograniczeniem tego jest jednak to, że można umieścić „{}” tylko na końcu polecenia, co wymaga użycia opcji mv --target-directory i, o ile wiem, jest to GNU-ism.