Próbuję uruchomić polecenie podobne do poniższego w skrypcie bash. Powinien przeszukiwać wszystkie podfoldery $sourcedir
i kopiować wszystkie pliki określonego typu na poziom główny $targetdir
.
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
To wydaje się być dość blisko, oprócz tego, że {}
nie jest przekazywana jako $2
do-exec sh -c ...
Chciałbym to zrobić tak blisko „właściwej drogi”, jak to możliwe, z tolerancją dla znaków specjalnych w nazwach plików (w szczególności znaków pojedynczego cudzysłowu).
Edycja: widzę ludzi sugerujących użycie xargs
lub tworzenie łańcuchów argumentów. Miałem wrażenie, że jest to w porządku tylko w przypadku ograniczonej liczby argumentów. Jeśli mam na przykład tysiące plików .jpg, które próbuję skopiować z wielu katalogów galerii do gigantycznego katalogu pokazu slajdów, czy rozwiązania łańcuchowe argumentów nadal będą działać?
Edycja 2: Mój problem polegał na tym, że brakowało _
mi przed pierwszą opcją sh w -exec
poleceniu. Dla każdego, kto jest ciekawy, jak sprawić, by polecenie find działało, dodaj _
i wszystko będzie dobrze:
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;
Przyjąłem odpowiedź poniżej, ponieważ spełnia to samo zadanie, ale jest bardziej wydajne i eleganckie.
xargs
kiedykolwiek został stworzony, aby automatycznie obsługiwać ogromne ilości argumentów na zwykłych komendach, które miały ograniczenia. Należy również wziąć pod uwagę, że większość maksymalnych limitów argumentów została znacznie ulepszona dla standardowych narzędzi GNU. Zauważysz także poprawę wydajności, unikając wszystkich tych forków procesowych, co w tysiącach plików jest istotne.