Oto bezpośrednia poprawka twojego podejścia:
find . -type f -name 'file*' -exec sh -c 'x="{}"; mv "$x" "${x}_renamed"' \;
Jest to jednak bardzo kosztowne, jeśli masz wiele pasujących plików, ponieważ uruchamiasz nową powłokę (która wykonuje a mv
) dla każdego dopasowania. A jeśli masz zabawne postacie w dowolnej nazwie pliku, to wybuchnie. Bardziej wydajne i bezpieczne podejście jest następujące:
find . -type f -name 'file*' -print0 | xargs --null -I{} mv {} {}_renamed
Ma także tę zaletę, że pracuje z dziwnie nazwanymi plikami. Jeśli find
obsługuje, można to zmniejszyć do
find . -type f -name 'file*' -exec mv {} {}_renamed \;
xargs
Wersja jest przydatna, gdy nie jest używany {}
, tak jak w
find .... -print0 | xargs --null rm
Tutaj rm
jest wywoływany raz (lub wiele plików wiele razy), ale nie dla każdego pliku.
Usunąłem basename
w tobie pytanie, ponieważ prawdopodobnie jest złe: przeniósłbyś foo/bar/file8
się file8_renamed
, nie foo/bar/file8_renamed
.
Edycje (zgodnie z sugestiami w komentarzach):
- Dodano skrócone
find
bezxargs
- Dodano naklejkę bezpieczeństwa
x
jest to bezużyteczne:find . -type f -name 'file*' -exec mv {} "{}_renamed" \;
xargs
wersja ma taką samą wydajność jak pierwszy przykład /