DEV Community

Alex Adam
Alex Adam

Posted on • Originally published at alexadam.dev

1 1

Convert Files and Folders Structures to Bash Scripts, with NodeJS

This is a simple NodeJS app that takes a source folder as input and generates a Bash script. The Bash script has all the files' content and the folders' structure in the source folder and it can recreate them when executed.

Source code available here: https://github.com/alexadam/folders-to-script

First step, iterate through all files in the source folder:

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

const listFiles = (dirPath, result) => {
 files = fs.readdirSync(dirPath)

 result = result || ['#!/bin/sh']

 for (const file of files) {
   ///...
 }

 return result
}

const allFiles = listFiles(rootPath)

fs.writeFileSync('./result.sh', allFiles.join('\n'))
Enter fullscreen mode Exit fullscreen mode

If file is a directory, add an mkdir -p command:

for (const file of files) {
 if (fs.statSync(dirPath + "/" + file).isDirectory()) {
 result.push(`mkdir -p ${path.join(dirPath, "/", file).replace(rootPath, '.')}`)
 result = listFiles(dirPath + "/" + file, result)
 } 
}

Else, test if file is binary or text, based on its extension:

const textExt = ['txt', 'md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
const binaryExt = ['jpg', 'png', 'gif', 'pdf', 'mp3', 'mp4'];

const getFileExt = (filePath) => filePath.split('.').pop()

...
    else {
      const filePath = path.join(dirPath, "/", file);
      const fileExt = getFileExt(filePath);
      const fileContent = fs.readFileSync(filePath);

      if (textExt.includes(fileExt)) {
        result.push(`
cat > ${path.join(dirPath, "/", file).replace(rootPath, '.')} << "EOF"
${fileContent}
EOF
`)
      } else if (binaryExt.includes(fileExt)) {
        const bindata = fileContent.toString('binary');
        const hexdata = new Buffer(bindata, 'ascii').toString('hex');
        result.push(`echo '${hexdata}' | xxd -r -p > ${path.join(dirPath, "/", file).replace(rootPath, '.')}`)
      }
    }
...

Binary files are stored as hex strings.

You can add/remove file extensions in the textExt or binaryExt arrays.

This is the full NodeJS script:

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

const rootPath = process.argv[2]

const textExt = ['txt', 'md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
const binaryExt = ['jpg', 'png', 'gif', 'pdf', 'mp3', 'mp4'];

const getFileExt = (filePath) => filePath.split('.').pop()

const listFiles = (dirPath, result) => {
  files = fs.readdirSync(dirPath)

  result = result || ['#!/bin/sh']

  for (const file of files) {
    if (fs.statSync(dirPath + "/" + file).isDirectory()) {
      result.push(`mkdir -p ${path.join(dirPath, "/", file).replace(rootPath, '.')}`)
      result = listFiles(dirPath + "/" + file, result)
    } else {
      const filePath = path.join(dirPath, "/", file);
      const fileExt = getFileExt(filePath);
      const fileContent = fs.readFileSync(filePath);

      if (textExt.includes(fileExt)) {
        result.push(`
cat > ${path.join(dirPath, "/", file).replace(rootPath, '.')} << "EOF"
${fileContent}
EOF
`)
      } else if (binaryExt.includes(fileExt)) {
        const bindata = fileContent.toString('binary');
        const hexdata = new Buffer(bindata, 'ascii').toString('hex');
        result.push(`echo '${hexdata}' | xxd -r -p > ${path.join(dirPath, "/", file).replace(rootPath, '.')}`)
      }
    }
  }

  return result
}

const allFiles = listFiles(rootPath)

fs.writeFileSync('./result.sh', allFiles.join('\n'))

Test it with node index.js test -> it will generate a Bash script file named result.sh

Then, in an empty directory, execute the script with sh result.sh.

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay