3

如果我可以精细地缩小那些我知道是任意的但在标准设置上没有被缩小的属性,我可以有效地减少我们的一些 JS 生产代码的大小。也就是说,当高级缩小设置太成问题时,以缩小的方式将它们替换为像“a”这样的单个字符。可以使用逗号分隔的已知可替换字符串列表将文本文件作为项目的一部分进行维护。

有没有人有可以实现这一点的 bat 或 shell 脚本,甚至是手动从 csv 中的每个文件?或者另一个实现相同目标的建议?我在 Windows 上,所以 sh 脚本需要在 Git bash 中工作,无论如何对我来说 :)

与查找/替换方面一样,需要生成替换字符串以使其唯一但尽可能短。

4

3 回答 3

2

好的,我在JSFiddle中发布了一个基本的 JavaScript / HTML 解决方案。这是没有 HTML 和 CSS 的 JavaScript 代码:

rndCh = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
rndLen = rndCh.length;

// Generate random string from number
function genRand(index) {
    var ni = [], rv = "";
    while (index > 0) {
        ni.push(index % 62);
        index = ~~(index / 62);
    }
    if (!ni.length) {
        ni.push(0);
    }
    while (ni.length > 0) {
        rv += rndCh[ni.pop()];
    }
    return rv;
}

$(document).ready(function() {
    $("#gobutton").on("click", function(e) {
        var prefix, code, rlist, ir, nrep, nrval;

        prefix = $("#myprefix").val();
        if (!prefix) {
            alert("Need prefix");
            return;
        }
        code = $("#mycode").val();
        if (!code) {
            alert("Need code");
            return;
        }
        rlist = $("#mylist").val();
        if (!rlist || !rlist.length) {
            alert("Need replacement list");
            return;
        }
        rlist = rlist.split(",");

        for (ir = 0;  ir < rlist.length;  ++ir) {
            if (rlist[ir]) {
                // Generate next random
                nrval = prefix + genRand(ir);
                nrep = new RegExp(rlist[ir], "g");
                code = code.replace(nrep, nrval);
            }
        }

        $("#myoutput").val(code);
    });
});
于 2012-09-12T18:28:32.200 回答
2

这是为那些不想使用 JavaScript 的人准备的 C++ 版本。它仅使用标准 C++ 库。

#include <stdio.h>
#include <io.h>
#include <string.h>

#include <vector>
#include <string>

void Usage(const char* msg = NULL)
{
    if (msg)
        printf("%s\n", msg);
    printf("Usage: coderep (prefix) (infile) (listfile) (outfile)\n");
}

char* OpenAndReadFile(const char* filename)
{
    FILE* fp = fopen(filename, "rb");
    if (!fp)
        return NULL;
    fseek(fp, 0, SEEK_END);
    int size = (int)ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char* buf = new char[size + 2];
    fread(buf, 1, size, fp);
    buf[size] = '\0';
    fclose(fp);
    return buf;
}

void ReplaceAll(std::string& str, const std::string& from, const std::string& to)
{
    size_t start_pos = 0;
    while ((start_pos = str.find(from, start_pos)) != std::string::npos)
    {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length();
    }
}

char* rndCh = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int rndLen = 62;

// Generate random string from number
void genRand(int index, std::string* str)
{
    std::vector<int> ni;
    while (index > 0)
    {
        ni.push_back(index % 62);
        index = index / 62;
    }
    if (!ni.size())
        ni.push_back(0);

    std::vector<int>::reverse_iterator ip;
    for (ip = ni.rbegin();  ip != ni.rend();  ++ip)
        (*str) += rndCh[*ip];
}

int main(int argc, char* argv[])
{
    if (argc != 5)
    {
        Usage();
        return 1;
    }

    // Read inputs and check parms
    const char* prefix = argv[1];
    char* code = OpenAndReadFile(argv[2]);
    if (!code || !*code)
    {
        Usage("Failed reading code");
        return 1;
    }
    char* list = OpenAndReadFile(argv[3]);
    if (!list || !*list)
    {
        delete[] code;
        Usage("Failed reading list");
        return 1;
    }
    const char* outfile = argv[4];
    if (!outfile || !*outfile)
    {
        Usage("Need output file");
        return 1;
    }

    // Split list
    std::string scode(code);
    std::vector<std::string> vlist;
    std::string acc;
    const char* lp = list;
    while (*lp)
    {
        if (*lp == L',')
        {
            vlist.push_back(acc);
            acc.clear();
        }
        else
        {
            acc += *lp;
        }
        ++lp;
    }
    if (acc.size() > 0)
        vlist.push_back(acc);

    // Do translation
    int index = 0;
    std::string rstr;
    std::vector<std::string>::iterator ilist;
    for (ilist = vlist.begin();  ilist != vlist.end();  ++ilist)
    {
        rstr = prefix;
        genRand(index, &rstr);
        ++index;

        ReplaceAll(scode, *ilist, rstr);
    }

    // Write results
    FILE* outp = fopen(outfile, "wb");
    if (!outp)
    {
        Usage("Error creating output file");
        return 1;
    }
    fwrite(scode.c_str(), sizeof(char), scode.size(), outp);
    fclose(outp);

    return 0;
}
于 2012-09-12T23:00:45.713 回答
1

既然你说 sed 可用,我已经在 sed 中测试了一个解决方案,以下应该可以解决问题:

sed -i -e 's:\bfirstNeedle\b:firstReplacement:g' -e 's:\bsecondNeedle\b:secondReplacement:g' [... and so on...] /path/to/first/file /path/to/second/file [etc...]

-i标志表示就地编辑(因此它会覆盖提供的原始文件(我当然会事先备份您的文件夹)。使用-e标志(表达式)轻松提供每个替换。替换本身就是s表示替换,后跟一个分隔符,一个与您要替换的内容匹配的正则表达式,另一个分隔符,然后是您要使用的替换;这也可以使用正则表达式中的分组,因此您可以执行以下操作(或任何其他此类技巧):

sed -i -e 's:\bget(([A-Z]{1,3})[a-zA-Z]*\(\)):g\1:g'

这将匹配 getter 并用 g[first-1-to-3-letters-of-next-word] 替换它们,从而轻松缩短它们。当然,这并不能保证唯一性,您必须自己确保这一点。

如果您有很多替换要做,您可以通过将它们成对放置在文件中original=replacement(每行一个)来创建表达式,然后用于echo $(sed -e "s:([^=]*)=(.*):-e\ 's=\b\1\b\2=g':" /path/to/replacements/file)打印替换列表。(这里我使用=分隔符只是为了让替换文件更容易理解和可能重复使用,随意使用你想要的任何分隔符)。

于 2012-09-13T08:59:52.490 回答