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.

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

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

Sign up