Jak przenieść (lub skopiować) wszystkie pliki określonego typu do katalogu w Uniksie?

22

Nie znam jeszcze wszystkich sztuczek grep/find/awk/xargs.

Powiedzmy, że mam kilka plików pasujących do określonego wzorca *.xxx. Te pliki znajdują się w losowych miejscach w określonym katalogu. Jak mogę znaleźć wszystkie takie pliki i przenieść je do folderu w moim katalogu domowym w systemie Unix (który może jeszcze nie istnieć)?

qodeninja
źródło
4
Musisz zachować ostrożność, mówiąc o „typie pliku”. W środowiskach unixy przykład „.xxx” nie jest nawet rozszerzeniem w sensie Windows. „.xxx” stanowi jedynie przyrostek nazwy pliku. „Typ pliku” jest bardziej jedną z kilku kategorii: zwykły plik, plik urządzenia, dowiązanie symboliczne, katalog, nazwany potok, gniazdo rodziny Unix, może kilka innych.
Bruce Ediger
1
Zobacz także: unix.stackexchange.com/questions/7027/…
jasonwryan
@BruceEdiger dzięki, myślę, że naprawdę miałem na myśli "wzorzec nazwy pliku"
qodeninja

Odpowiedzi:

22
mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;
Kevin
źródło
1
Chciałbym użyćmv -i -t ~/dst {} +
enzotib
17

Jeśli chcesz przenieść wszystkie pliki w hierarchii katalogów do jednego katalogu docelowego, w bash ≥4 (wstaw shopt -s globstarw swoim ~/.bashrc) lub zsh:

mkdir ~/new-directory
mv -i **/*.xxx ~/new-directory

W innych muszlach:

mkdir ~/new-directory
find . -name '*.xxx' -exec mv -i {} ~/new-directory \;

Jak odczytać to findpolecenie:

  • .: przeglądaj bieżący katalog
  • -name '*.xxx': działają na plikach, których nazwa pasuje do tego wzorca
  • -exec … \;: wykonaj to polecenie dla każdego pliku, zastępując {}ścieżkę do pliku

Istnieje bardziej złożone polecenie, findktóre jest szybsze, jeśli masz wiele plików, ponieważ nie trzeba wywoływać osobnego mvprocesu dla każdego pliku:

find . -name '*.xxx' -exec sh -c 'mv -i "$@" "$0"' ~/new-directory {} +

Na +końcu findznajduje się polecenie uruchomienia polecenia na wielu plikach jednocześnie. Ponieważ findnazwy plików mogą znajdować się tylko na końcu wiersza poleceń, a mvkatalog docelowy musi być na końcu, używamy powłoki pośredniej do zmiany kolejności argumentów ( "$0"jest to pierwszy argument powłoki ~/new-directoryi "$@"są to kolejne argumenty pochodzące z findrozszerzenie {}).

Gilles „SO- przestań być zły”
źródło
4

Jeśli chcesz zreplikować strukturę katalogów pasujących plików źródłowych do nowego katalogu docelowego, możesz skorzystać z opcji --parents GNU cp :

mkdir /path/to/target_dir
cd source_dir
find . -name '*.xxx' -exec cp -iv --parents -t /path/to/target_dir {} +
frielp
źródło
3

można użyć find bez -exec‍, a także:

mkdir /path/to/dest    
cp `find /path/to/source -name "*.jar"` /path/to/dest
Ken Zein
źródło
1
Zauważ jednak, że find -execjest to znacznie bezpieczniejsze; powyższe nie powiedzie się na przykład w nazwach plików zawierających białe znaki.
wtorek