Gdybym chciał, aby skopiować wszystkie *.so
pliki src
do dst
zrobiłbym:
cp src/*.so dst
Chcę jednak skopiować wszystkie *.so
pliki z src i jego podkatalogów do dst
. Jakieś wskazówki?
Gdybym chciał, aby skopiować wszystkie *.so
pliki src
do dst
zrobiłbym:
cp src/*.so dst
Chcę jednak skopiować wszystkie *.so
pliki z src i jego podkatalogów do dst
. Jakieś wskazówki?
Odpowiedzi:
Próbować:
find src/ -type f | grep -i so$ | xargs -i cp {} dst
grep
znacznie przewyższają proste wzorce powłoki używane w -name
parametrze do find
. xargs
jest również znacznie potężniejszy niż -exec
parametr do find
.
Jeśli używasz Bash, możesz włączyć globstar
opcję powłoki, aby rekurencyjnie dopasowywać pliki i katalogi:
shopt -s globstar
cp src/**/*.so dst
Jeśli chcesz znaleźć pliki, których nazwy zaczynają się od .
, i / lub pliki w i pod katalogami, których nazwy zaczynają się od .
, ustaw dotglob
również opcję (np. Z shopt -s dotglob
). Możesz ustawić je oba za pomocą jednego polecenia:
shopt -s globstar dotglob
Wypróbowałem polecenie sugerowane przez Mike'a:
find src/ -type f | grep -i so$ | xargs -i cp {} dst
ale skończyło się to zrzuceniem wszystkich plików do katalogu dst
z utratą ich ścieżek względnych.
Aby zachować ścieżki względne, polecenie należy zmodyfikować w następujący sposób:
find src/ -type f | grep -i so$ | xargs -i cp {} dst/{}
dst
. Jeśli tak nie jest, użyj cp --parents
. Pamiętaj też, aby podać nazwy plików. Zatem: ... | xargs -i cp --parents "{}" dst
(zauważ, że ostatnim argumentem cp
jest teraz „tylko” katalog docelowy). Polecenie może być wykonane nawet krótszy (i prawdopodobnie szybciej) przy użyciu -t
flagi: ... | xargs cp --parents -t dst
.
... | xargs cp {} --parents -t dst.
--parents
nie jest dostępny. Użyłem ditto
zamiast niego: stackoverflow.com/questions/11246070/cp-parents-option-on-mac
Kolejny sposób to zrobić:
find src/ -type f -name "*.so" -exec cp {} dst/ \;
cp
procesów: ... -exec cp -t dst/ {} +
.
-exec
się ;
, {}
otrzymuje jedną ścieżkę naraz. Dostajesz osobny cp
dla każdego pliku. Z +
składniowych find
replaces {}
z wieloma wynikami (do granicy systemowej zdefiniowanej długości linii poleceń ograniczeń: {}
musi być ostatnią rzeczą przed +
, stąd cp -t
). Tworzenie i kończenie procesu jest względnie kosztowne. Z tego powodu warto go używać, +
gdy oczekuje się wielu wyników. W takim przypadku kopiowanie dużej liczby plików i tak może zająć dużo czasu, więc różnica może minąć niezauważona; niemniej jednak jest to dobra praktyka.
Grep można zastąpić za pomocą polecenia find's -name :
find src/ -type f -name "*.so" | xargs -i cp {} dst/{}
find
Potrafi dopasowywać wzorce i wykonywać polecenia. Nie trzeba przesyłać danych wyjściowych:find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'