Chci přejmenovat více souborů (file1 … fileN to file1_renamed … fileN_renamed) pomocí find
příkaz:
find . -type f -name 'file*' -exec mv filename='{}' $(basename $filename)_renamed ';'
Ale zobrazuje se tato chyba:
mv: cannot stat ‘filename=./file1’: No such file or directory
Toto nefunguje, protože název souboru není interpretován jako proměnná shellu.
Přijatá odpověď:
Toto je přímá oprava vašeho přístupu:
find . -type f -name 'file*' -exec sh -c 'x="{}"; mv "$x" "${x}_renamed"' \;
To je však velmi drahé, pokud máte mnoho odpovídajících souborů, protože spustíte nový shell (který spustí mv
) pro každý zápas. A pokud máte v libovolném názvu souboru vtipné znaky, bude to explodovat. Efektivnější a bezpečnější přístup je tento:
find . -type f -name 'file*' -print0 | xargs --null -I{} mv {} {}_renamed
Výhodou je také práce s podivně pojmenovanými soubory. Pokud find
podporuje, lze to zredukovat na
find . -type f -name 'file*' -exec mv {} {}_renamed \;
xargs
verze je užitečná, když nepoužíváte {}
, jako v
find .... -print0 | xargs --null rm
Zde rm
se volá jednou (nebo se spoustou souborů několikrát), ale ne pro každý soubor.
Odebral jsem basename
ve vaší otázce, protože je to pravděpodobně špatně:přesunuli byste foo/bar/file8
na file8_renamed
, nikoli foo/bar/file8_renamed
.
Úpravy (jak je navrženo v komentářích):
- Přidáno zkrácené
find
bezxargs
- Přidána bezpečnostní nálepka