Translate

Поиск по этому блогу

вторник, 1 октября 2019 г.

Node.js - Переименование файлов.

Сегодня мы познакомимся с файловой системой Node.js, а именно с массовым переименованием файлов в определенной папке (директории)



Ранее, я много писал о работе с Node.js. Если вы что-то пропустили, то посмотрите в разделе "Карта сайта". Можете воспользоваться поиском по сайту, или выбрать посты о Node.js по ярлыку. Можете просто пройти по ссылке в начале абзаца на оглавление сайта, а именно к разделу о Node.js.

Самый надежный способ получать знание это написать что-то полезное! Сегодня, я предлагаю написать простой скрипт, который будет брать некоторые фото (image.jpg) и менять их название на что-то более-менее вразумительное нежели бессвязный набор символов.

Например: У меня на компьютере есть некая папка "srcImage", в которой лежат файлы с разнообразными именами, которые мы хотим изменить. Переименованные файлы мы будем сохранять или в этой же папке, или в любой другой папке (директории).

В Node.js есть встроенный модуль - fs - File System, который предоставляет нам такую ( и множество других) полезную возможность. Мы им и воспользуемся.

Если посмотреть документацию, то там все очень очень просто:

fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  console.log('renamed complete');
});


Обязательно посмотрите в этом блоге -Как правильно задать путь к файлу. Это значительно облегчит вашу жизнь в дальнейшем!
В приведенном примере из документации, все очень просто:

/tmp/hello - относительный путь к папке в которой нужно переименовать файлы и сам файл.

/tmp/world - относительный путь к папке в которую нужно положить переименованный файл и сам файл.

Если будет ошибка, то отследить её в консоли, а если успех, то вывести сообщение, что все прошло успешно.

Нашу задачу мы разобьем на такие подзадачи:
  1. Выбрать шаблон для переименования - придания однотипности новым именам файла.
  2. Получить последовательный доступ к файлам, которые лежат в определенной директории для переименования.
  3. Изменить значение каждого файла на удобное.
  4. Отправить файлы в нужную папку.
  5. Поймать ошибку в случае неудачи или подтверждение - в случае успеха.


Выбрать шаблон для переименования

Вы можете сделать это по собственному усмотрению. Например - задать его из определенного количества случайных цифр и букв ( но тогда он ничем не будет отличаться от исходных :-) ) Или задать некое строковое значение. Например: "My_favorite_file", "vacation" и т.д.

Я решил использовать дату в формате дд-мм-гг (01-10-2019). К дате мы будем добавлять порядковый номер файла в папке и некое префиксное значение. Его я добавил, потому что я часто перемещаю файлы в различные папки и мне удобно знать изначальное место хранения данного файла.

Итак, приступаем. Создадим файл, например rename.js

Первым делом импортируем в него нужный нам модуль:const fs = require("fs");

Получим дату в нужном формате и выведем её в консоль:

const fs = require("fs");

var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1;
var curr_year = d.getFullYear();

var data_f = curr_date + "-" + curr_month + "-" + curr_year;
console.log(data_f);
// 1-10-2019


  1. Если вы работаете, как и я в VS-Code, то сделать это очень просто нажатием клавиш Ctrl + Shift + Ё `(открыть консоль) и запустить код - Ctrl + Alt + N (с расширением code runner) или другим способом.

  2. Посмотреть список установленных расширений - просто введите в консоль code --list-extensions и нажмите Enter

  3. Проще всего запустить файл из Node.js - находясь в нужной директории, набрать в консоли node и имя_файла. В нашем случае это node rename. Именно так мы и будем делать, потому как наш скрипт будет работать на Node.js.

Получить последовательный доступ к файлам

Для того, чтобы получить каждый отдельный файл в папке (srcImage) , мы воспользуемся встроенным методом fs.readdir. По ссылке, вы можете прочитать официальную документацию.

Для того, чтобы этот метод сработал правильно, мы должны передать в него первым аргументом - путь к файлам, а вторым - функцию обратного вызова (callback-function) в которую первым аргументом передадим ошибку - err, а вторым полученные файлы, который и выведем в консоль методом forEach, в который дополнительно передадим порядковый номер файла - i. В консоли покажем каждый файл с соответствующим ему порядковым номером i

const fs = require("fs");
const srcFolder = "C:/Users/Branch/Node/abc-rename-file/srcImage/";
var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1;
var curr_year = d.getFullYear();

var data_f = curr_date + "-" + curr_month + "-" + curr_year;

fs.readdir(srcFolder, (err, files) => {
  files.forEach((file, i) => {
    console.log(`${file} i=${i}`);   
  });
});



В переменную srcFolder нам следует поместить относительный, но лучше (для будущего использования) абсолютный путь к файлу в виде строкового значения.

запускаем наш код :

node rename


И теперь в консоли мы увидим все файлы из папки с порядковыми номерами.



Изменить значение каждого файла.

Для наглядности, я создам папку, куда мы будем перемещать переименованные файлы в другой директории и назову ее outImage. В наш код помещу абсолютный путь к ней в переменную outFolder:

const outFolder = "C:/Users/Euroset/GoogleD/outFolder/";

Как я говорил ранее, я создам дополнительно свой префикс, который добавлю к дате, полученной ранее:

var myPrefix = "y";
var prefix = myPrefix + data_f;


Сейчас, нам остается воспользоваться встроенным методом для переименования файлов, о котором я говорил ранее и добавить к имени наш префикс и порядковый номер, ну и конечно не забыть поймать ошибку, если есть или вывести сообщение об успехе:

fs.rename(srcFolder + file, outFolder + i + prefix + ".jpg", err => {
      if (err) throw err;
      console.log("rename completed!");
    });



запускаем наш код :

node rename


В консоль получим многократный вывод сообщения об успешном завершении операции. Папка srcImage пуста, а в новой папке outFolder появились переименованные соответствующим образом файлы:



rename полностью:
const fs = require("fs");
const srcFolder = "C:/Users/Branch/Node/abc-rename-file/srcImage/";
const outFolder = "C:/Users/GoogleD/outFolder/";

var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1;
var curr_year = d.getFullYear();

var data_f = curr_date + "-" + curr_month + "-" + curr_year;
var myPrefix = "y";
var prefix = myPrefix + data_f;

fs.readdir(srcFolder, (err, files) => {
  files.forEach((file, i) => {
    fs.rename(srcFolder + file, outFolder + i + prefix + ".jpg", err => {
      if (err) throw err;
      console.log("rename completed!");
    });
  });
});



Таким образом, мы создали простой скрипт, который позволяет переименовывать (задавать имена) файлам и перемещать их в нужную директорию. Это может не только помочь вам в изучении Node.js, но и значительно сэкономить время.

Этот скрипт можно дорабатывать бесконечно. Можно сделать очень много различных манипуляций. Есть предложения? Пишите в комментариях!

Удачного кодирования - Happy coding и до скорых встреч.

Не забывайте подписаться на мою страницу в фейсбуке, посмотреть новости в телеграм-канале и в группе.

Посмотреть код на gitHub abc-rename-files-with-node commit - "rename files with Node.js"



UPDATE: По многочисленным просьбам публикую приятные дополнения, которые позволят:
  1. Легко и быстро запускать скрипт из любой директории.
  2. Сохранять исходное расширение файла.
1. Для этого нам нужно воспользоваться встроенным модулем path. Первое, что нам нужно сделать, это импортировать его в наш скрипт:

var path = require("path");

После этого, мы можем автоматически получать путь к директории, в которой расположен наш скрипт, методом __dirname()

Предположим, что файлы, которые мы будем изменять, лежат в некоей общей для них директории (например - Common как на рис. ниже) и в папке с именем srcImage . В этой же директории мы создадим папку для измененных файлов - outImage

Файловая структура выглядит вот так:



Теперь мы можем легко прописать путь в папку исходных и измененных файлов:

const srcFolder = path.resolve(__dirname, "srcImage") + "/";
const outFolder = path.resolve(__dirname, "outImage") + "/";

Этот скрипт можно легко запустить, если в проводнике виндовс, выбрать нужную папку (на схеме - Common Folder), нажать правую кнопку мыши и , если у вас установлен Bash (а он идет вместе с Node.js), выбрать - Git Bash Here. Таким образом, вы откроете терминал сразу в нужной папке.

Если у вас не получилось, то перейдите в нужную директорию командой

cd folder_name


Теперь, для запуска скрипта нужно набрать:

node rename


2. Для того, чтобы сохранять расширения у изменяемых файлов, нам нужно опять воспользоваться тем же модулем path и внутри цикла forEach получить расширение файла, сохранив его в изменяемую переменную:

let extension = path.extname(file);

Теперь, нам остается заменить, внутри функции fs.rename добавляемое окончание (расширение) файла - ".jpg", на extension

fs.rename(srcFolder + file, outFolder + i + prefix + extension, err => {
      if (err) throw err;
      console.log("rename completed!");
    });


Код из файла rename.js полностью:

const fs = require("fs");
var path = require("path");

const srcFolder = path.resolve(__dirname, "srcImage") + "/";
const outFolder = path.resolve(__dirname, "outImage") + "/";

var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1;
var curr_year = d.getFullYear();

var data_f = curr_date + "-" + curr_month + "-" + curr_year;
var myPrefix = "-t-t-t-";
var prefix = myPrefix + data_f;

fs.readdir(srcFolder, (err, files) => {
  files.forEach((file, i) => {
    let extension = path.extname(file);
    fs.rename(srcFolder + file, outFolder + i + prefix + extension, err => {
      if (err) throw err;
      console.log(`rename - ${file} completed!`);
    });
  });
});



Теперь, если нам нужно поменять название всех файлов в некоторой папке, то мы копируем этот файл и вставляем его на одну директорию выше тех папок - srcImage (исходные изображения) outImage (пустая, вновь созданная, куда будут помещены переименованные файлы).



Открываем rename.js в редакторе и меняем srcImage и outImage на названия ваших папок. Можно это делать и в одной папке, без создания дополнительной outImage, для готовых файлов. В этом случае у вас будут совпадать названия, которые вы вставите на место указанных мной srcImage и outImage.

Префикс, вы можете установить по своему усмотрению и вкусу. Я поставил произвольный - -t-t-t- .

Для примера я поместил в папку srcImage тестовые файлы с разными расширениями:



Теперь, открываю gitBash, как я описывал выше, в CommonFolder и запускаю скрипт:

node rename




В терминале, я вижу перечисленные в порядке процесса переименования файлы ( старые их названия).

Идем в папку переименованных файлов и видим:



Переименование файлов прошло успешно!

Вот и все, собственно. Теперь запускаем файл в любой директории, о чем я написал выше и получаем измененными только имена файла, а не их расширения.



Посмотреть код на gitHub abc-rename-files-with-node commit - "renaming files using path and saving extension"

                                                                                                                                                             

Телеграм канал - Full Stack JavaScript Developer
Помочь проекту (любая валюта). DONATE


Хотите освоить самые современные методы написания React приложений? Надоели простые проекты? Нужны курсы, книги, руководства, индивидуальные занятия по React и не только? Хотите стать разработчиком полного цикла, освоить стек MERN, или вы только начинаете свой путь в программировании, и не знаете с чего начать, то пишите через форму связи, подписывайтесь на мой канал в Телеге, вступайте в группу на Facebook.Пишите мне - kolesnikovy70 почта gmail.com