Próbuję uruchomić polecenie podobne do poniższego w skrypcie bash. Powinien przeszukiwać wszystkie podfoldery $sourcediri 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 $2do-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 xargslub 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 -execpoleceniu. 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.
xargskiedykolwiek 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.