Skip to content

Instantly share code, notes, and snippets.

@davmac314
Last active October 15, 2017 22:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davmac314/d8c9a1f9b73a9587deb4fa9ac66b34db to your computer and use it in GitHub Desktop.
Save davmac314/d8c9a1f9b73a9587deb4fa9ac66b34db to your computer and use it in GitHub Desktop.
#include <iostream>
#include <fstream>
#include <utility>
#include <regex>
#include <experimental/filesystem>
// Recursively replace shebang lines with correct interpreter paths according to regex rules
namespace fs = std::experimental::filesystem;
// Define regexes and their replacements here:
std::pair<std::regex, std::string> regexes[] = {
{ std::regex("^#!/(.*)/perl\\b"), "#!/usr/bin/perl" },
{ std::regex("^#!/(.*)/python\\b"), "#!/usr/bin/python" }
};
// Replace first line of a specified file (infile) at path (p1) with given line (line)
void replace_file(const fs::path &p1, std::ifstream &infile, std::string &line)
{
auto p2 = p1;
p2.replace_filename(".temp.xxx");
std::ofstream outfile(p2);
outfile << line << std::endl;
// Copy remaining lines from infile to outfile:
std::string rline;
while (std::getline(infile, rline)) {
outfile << rline << std::endl;
}
fs::rename(p2, p1);
}
void process_file(const fs::path &p1)
{
// std::cout << "processing file: " << p1 << std::endl;
std::ifstream infile(p1);
std::string orig_line;
if (std::getline(infile, orig_line)) {
auto line = orig_line;
for (auto &regex : regexes) {
line = std::regex_replace(line, regex.first, regex.second);
}
if (line != orig_line) {
replace_file(p1, infile, line);
}
}
}
void process_path(const fs::path &p1)
{
// std::cout << "processing path: " << p1 << std::endl;
for (auto &entry : fs::directory_iterator(p1)) {
if (fs::is_directory(entry.path())) {
process_path(entry.path());
}
else {
process_file(entry.path());
}
}
}
int main(int argc, char **argv)
{
fs::path p1 = argv[1];
if (argc < 2 || ! fs::is_directory(p1)) {
std::cerr << "Too few arguments / not a path" << std::endl;
return 1;
}
process_path(p1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment