Вместо того, чтобы писать одну большую сложную функцию, я предложу более разложенный подход.
Сначала мы начнем с files
, который рекурсивно перечисляет все файлы с указанным path
-
const { readdir, stat } =
require ("fs") .promises
const { join } =
require ("path")
const files = async (path = ".") =>
(await stat (path)) .isDirectory ()
? Promise
.all
( (await readdir (path))
.map (f => files (join (path, f)))
)
.then
( results =>
[] .concat (...results)
)
: [ path ]
У нас есть способ перечислить все файлы сейчас, но мы хотим переименовать только некоторые из них.Мы напишем обобщенную функцию search
, чтобы найти все файлы, которые соответствуют запросу -
const { basename } =
require ("path")
const search = async (query, path = ".") =>
(await files (path))
.filter (x => basename (x) === query)
Теперь мы можем написать вашу renameFiles
функцию как специализацию search
-
const { rename } =
require ("fs") .promises
const { dirname } =
require ("path")
const renameFiles = async (from = "", to = "", path = ".") =>
Promise
.all
( (await search (from, path))
.map
( f =>
rename
( f
, join (dirname (f), to)
)
)
)
Чтобы использовать его, мы просто вызываем renameFiles
с его ожидаемыми параметрами -
renameFiles ("foo", "bar", "path/to/someFolder")
.then
( res => console .log ("%d files renamed", res.length)
, console.error
)
// 6 files renamed
Рассматривая наши программы выше, мы видим некоторые паттерны, возникающие при использовании Promise.all
, await
и map
.Действительно, эти шаблоны могут быть извлечены, и наши программы могут быть еще более упрощены.Вот files
и renameFiles
, пересмотренные для использования универсального модуля Parallel
-
const files = async (path = ".") =>
(await stat (path)) .isDirectory ()
? Parallel (readdir (path))
.flatMap (f => files (join (path, f)))
: [ path ]
const renameFiles = (from = "", to = "", path = "") =>
Parallel (search (from, path))
.map
( f =>
rename
( f
, join (dirname (f), to)
)
)
Модуль Parallel
был первоначально получен в в этой связанной Q & A .Для получения дополнительной информации и объяснений, пожалуйста, перейдите по ссылке.