C# 用于解析和更改数字的脚本

C# 用于解析和更改数字的脚本,c#,scripting,numbers,fileparsing,C#,Scripting,Numbers,Fileparsing,在编辑特定类型的文件时,我经常使用数字,这是一项乏味的工作。该文件的格式如下: damagebase = 8.834 "abc_foo.odf" 3.77 "def_bar.odf" 3.77 "ghi_baz.odf" 3.77 "jkl_blah.odf" 4.05 ... 对于编写一个脚本来解析这个数字并让我以编程方式更改每个数字,您有什么建议 语言:我使用C#,一些F#(noob)和Lua。如果您建议使用正则表达式,您能提供一些具体的正则表达式吗

在编辑特定类型的文件时,我经常使用数字,这是一项乏味的工作。该文件的格式如下:

damagebase = 8.834
    "abc_foo.odf" 3.77
    "def_bar.odf" 3.77
    "ghi_baz.odf" 3.77
    "jkl_blah.odf" 4.05
    ...
对于编写一个脚本来解析这个数字并让我以编程方式更改每个数字,您有什么建议


语言:我使用C#,一些F#(noob)和Lua。如果您建议使用正则表达式,您能提供一些具体的正则表达式吗?因为我不熟悉它们。

Perl非常适合这样的东西。下面是一个perl脚本,它将执行您想要的操作

#!/usr/bin/env perl

$multiplier = 2.0;

while (<>)
{
    $n = /=/ ? 2 : 1;
    @tokens = split;
    $tokens[$n] *= $multiplier;

    print "\t" if not /=/;
    print join(' ', @tokens) . "\n";
}

Perl非常适合这样的东西。下面是一个perl脚本,它将执行您想要的操作

#!/usr/bin/env perl

$multiplier = 2.0;

while (<>)
{
    $n = /=/ ? 2 : 1;
    @tokens = split;
    $tokens[$n] *= $multiplier;

    print "\t" if not /=/;
    print join(' ', @tokens) . "\n";
}

您可以将非空格和punt的运行匹配到:


您可以将非空格和punt的运行匹配到:


如果这就是您真正想要做的,请使用awk:

awk '{$NF *= 2.5 ; print }' < input_file > output_file
awk'{$NF*=2.5;print}'output\u file
编辑:好吧,如果你想保持你所描述的空白,这应该是可行的(尽管它越来越不雅观)

awk'{$NF*=2.5}/^\“/{print”\t“$0}!/^\“/{print}”output\u file

如果您真的只想这么做,请使用awk:

awk '{$NF *= 2.5 ; print }' < input_file > output_file
awk'{$NF*=2.5;print}'output\u file
编辑:好吧,如果你想保持你所描述的空白,这应该是可行的(尽管它越来越不雅观)

awk'{$NF*=2.5}/^\“/{print”\t“$0}!/^\“/{print}”output\u file
我试过了

static void Main(string[] args)
{
    Console.WriteLine("Please enter the multiplier:");
    string stringMult = Console.ReadLine();
    int multiplier;
    Int32.TryParse(stringMult, out multiplier);
    StreamReader sr = new StreamReader(@"C:\Users\[obscured]\Desktop\Fleetops Mod\Data To Process.txt", true);
    string input = sr.ReadToEnd();
    sr.Close();
    StreamWriter sw = new StreamWriter(@"C:\Users\[obscured]\Desktop\Fleetops Mod\Data To Process.txt", false);
    Regex r = new Regex(@"^(\w+)\s*=\s*(\S+)" +
            @"(?:\s+""([^""]+)""\s+(\S+))+",
            RegexOptions.Compiled | RegexOptions.MultiLine);
    Match m = r.Match(input);
    if (m.Success) {
        double header = Double.Parse(m.Groups[2].Value);
        sw.WriteLine("{0} = {1}", m.Groups[1].Value,
                         header * multiplier);
        CaptureCollection files = m.Groups[3].Captures;
        CaptureCollection nums  = m.Groups[4].Captures;
        for (int i = 0; i < files.Count; i++) {
            double val = Double.Parse(nums[i].Value);
            sw.WriteLine(@"  ""{0}"" {1}", files[i].Value,
                                val * multiplier);
        }
    }
    else
        Console.WriteLine("no match");
    sw.Close();
    Console.WriteLine("Done!");
    Console.ReadKey();
}
我的理论是,因为每个非标题行前面的空白是一个制表符(在这里它不会以这种方式显示),所以正则表达式不匹配。如果你想知道,空格很重要。

我试过了

static void Main(string[] args)
{
    Console.WriteLine("Please enter the multiplier:");
    string stringMult = Console.ReadLine();
    int multiplier;
    Int32.TryParse(stringMult, out multiplier);
    StreamReader sr = new StreamReader(@"C:\Users\[obscured]\Desktop\Fleetops Mod\Data To Process.txt", true);
    string input = sr.ReadToEnd();
    sr.Close();
    StreamWriter sw = new StreamWriter(@"C:\Users\[obscured]\Desktop\Fleetops Mod\Data To Process.txt", false);
    Regex r = new Regex(@"^(\w+)\s*=\s*(\S+)" +
            @"(?:\s+""([^""]+)""\s+(\S+))+",
            RegexOptions.Compiled | RegexOptions.MultiLine);
    Match m = r.Match(input);
    if (m.Success) {
        double header = Double.Parse(m.Groups[2].Value);
        sw.WriteLine("{0} = {1}", m.Groups[1].Value,
                         header * multiplier);
        CaptureCollection files = m.Groups[3].Captures;
        CaptureCollection nums  = m.Groups[4].Captures;
        for (int i = 0; i < files.Count; i++) {
            double val = Double.Parse(nums[i].Value);
            sw.WriteLine(@"  ""{0}"" {1}", files[i].Value,
                                val * multiplier);
        }
    }
    else
        Console.WriteLine("no match");
    sw.Close();
    Console.WriteLine("Done!");
    Console.ReadKey();
}
我的理论是,因为每个非标题行前面的空白是一个制表符(在这里它不会以这种方式显示),所以正则表达式不匹配。如果您想知道,空格是很重要的。

您可以像这样使用AWK(注意格式是如何很容易转换的)

在此示例脚本中,我将第2列乘以
3.1

请注意,要恢复格式,
在printf的开头插入了一个选项卡,
这两个
sed
命令将您的格式转换为适合AWK命令的格式

您可以这样使用AWK(请注意,格式是如何轻松转换的)

在此示例脚本中,我将第2列乘以
3.1

请注意,要恢复格式,
在printf的开头插入了一个选项卡,


这两个
sed
命令将您的格式转换为适用于AWK命令的格式

请提供更多详细信息。这里有两种不同的行格式。“damagebase”格式是否会在文件中再次出现,或者它是某种类型的头文件?您想通过编程更改所有数字还是仅更改非标题数字?更改数字的方法有多复杂?它是一个简单的加法,还是更复杂,比如应用运行平均数?损伤基线是一个标题,我只想对每一行(包括标题)上的数字应用一个乘法器。我很感激你对c#答案感到更舒服,但一般来说,你真的应该学习足够多的perl或awk,这样你就不必求助于c来解决这类问题。我对正则表达式有一个问题。“我在这里使用了正确的数字批处理字符吗?我如何匹配它?哎呀!它吃掉了我的字符串…”:请详细说明。这里有两种不同的行格式。“damagebase”格式是否会在文件中再次出现,或者它是某种类型的头文件?您想通过编程更改所有数字还是仅更改非标题数字?更改数字的方法有多复杂?它是一个简单的加法,还是更复杂,比如应用运行平均数?损伤基线是一个标题,我只想对每一行(包括标题)上的数字应用一个乘法器。我很感激你对c#答案感到更舒服,但一般来说,你真的应该学习足够多的perl或awk,这样你就不必求助于c来解决这类问题。我对正则表达式有一个问题。“我在这里使用了正确的数字批处理字符吗?我如何匹配它?咦!它吃掉了我的字符串…”:d这吃掉了非标题行上的前导制表符。嗯,我真的没听说过awk。这是什么?好吧,你有疯狂的awk技能。如果可以的话,我会投+100。这会吃掉非标题行上的前导标签。嗯,我真的没听说过awk。这是什么?好吧,你有疯狂的awk技能。如果可以的话,我会投票给+100。Perl确实更适合这些问题。为了展示如何轻松编写脚本,我在另一个答案中添加了一个AWK表单。Perl确实更适合这些问题。为了展示如何轻松编写脚本,我在另一个答案中添加了一个AWK表单。啊,已经有另一个AWK答案了。我没有注意到。然而,你可以看到为你的目的编写脚本的各种方式。啊,已经有了另一个AWK答案。我没有注意到。但是,您可以看到为您的目的编写脚本的各种方式。我的答案中也有同样的修改。我第一次尝试时,它运行得很好,但我能够通过在标题行之前添加一个空行来重现您看到的行为。在正则表达式中,^表示“字符串的开头”,但通过“多行”选项,它可以匹配任何行的开头。还请注意\s匹配空格,其中包括空格和制表符。现在它运行,但输出中的每个数字都设置为零。我会再花点时间看看能不能让它工作。。。有什么不一样的原因吗?我知道原因了。不知何故,乘数被设置为zro。为什么会这样?我没有发现我给它的输入号码有什么问题…我知道了。这是一个修复输入类型的问题。
static void Main(string[] args)
{
    Console.WriteLine("Please enter the multiplier:");
    string stringMult = Console.ReadLine();
    int multiplier;
    Int32.TryParse(stringMult, out multiplier);
    StreamReader sr = new StreamReader(@"C:\Users\[obscured]\Desktop\Fleetops Mod\Data To Process.txt", true);
    string input = sr.ReadToEnd();
    sr.Close();
    StreamWriter sw = new StreamWriter(@"C:\Users\[obscured]\Desktop\Fleetops Mod\Data To Process.txt", false);
    Regex r = new Regex(@"^(\w+)\s*=\s*(\S+)" +
            @"(?:\s+""([^""]+)""\s+(\S+))+",
            RegexOptions.Compiled | RegexOptions.MultiLine);
    Match m = r.Match(input);
    if (m.Success) {
        double header = Double.Parse(m.Groups[2].Value);
        sw.WriteLine("{0} = {1}", m.Groups[1].Value,
                         header * multiplier);
        CaptureCollection files = m.Groups[3].Captures;
        CaptureCollection nums  = m.Groups[4].Captures;
        for (int i = 0; i < files.Count; i++) {
            double val = Double.Parse(nums[i].Value);
            sw.WriteLine(@"  ""{0}"" {1}", files[i].Value,
                                val * multiplier);
        }
    }
    else
        Console.WriteLine("no match");
    sw.Close();
    Console.WriteLine("Done!");
    Console.ReadKey();
}
damagebase = 8.098
    "bor_adaptor_03.odf" 3.77
    "bor_adaptor_13.odf" 3.77
    "bor_adaptor_23.odf" 3.77
    "bor_adaptor_33.odf" 4.05
    "bor_adaptor_R3.odf" 3.77
    "bor_adaptor_T3.odf" 3.77
    "bor_cube_BHHHMM.odf" 6.48
    "bor_cube_BRHHHM.odf" 4.52
    "bor_cube_BRHHMM.odf" 6.48
    "bor_cube_BTHHHM.odf" 4.52
    "bor_cube_BTHHMM.odf" 6.48
    "bor_cube_BTRHHM.odf" 4.52
    "bor_cube_BTRHMM.odf" 6.48
    "bor_cube_BTTHHM.odf" 4.52
    "bor_cube_BTTHMM.odf" 6.48
    "bor_cube_BTTRHM.odf" 4.52
    "bor_cube_BTTRMM.odf" 6.48
    "bor_cube_BTTTHM.odf" 4.52
    "bor_cube_BTTTMM.odf" 6.48
    "bor_cube_BTTTRM.odf" 4.52
    "bor_cube_RHHHMM.odf" 6.48
    "bor_cube_THHHMM.odf" 6.48
    "bor_cube_TRHHHM.odf" 4.52
    "bor_cube_TRHHMM.odf" 6.48
    "bor_cube_TTHHHM.odf" 4.52
    "bor_cube_TTHHMM.odf" 6.48
    "bor_cube_TTRHHM.odf" 4.52
    "bor_cube_TTRHMM.odf" 6.48
    "bor_cube_TTTHHM.odf" 4.52
    "bor_cube_TTTHMM.odf" 6.48
    "bor_cube_TTTRHM.odf" 4.52
    "bor_cube_TTTRMM.odf" 6.48
    "dom_battle_cruiserY2r6.odf" 4.123
    "dom_battle_cruiserYr6.odf" 4.123
    "dom_battle_cruiserZ2r6.odf" 4.123
    "dom_battle_cruiserZr6.odf" 4.123
    "dom_battle_cruiser_fed2r6.odf" 4.123
    "dom_battle_cruiser_fedr6.odf" 4.123
    "dom_defenderr4.odf" 7.775
    "dom_defenderr5.odf" 7.452
    "dom_defenderr6.odf" 3.793
    "dom_dreadnought_borr4.odf" 3.77
    "dom_dreadnought_borr5.odf" 3.77
    "dom_dreadnought_borr6.odf" 3.77
    "dom_dreadnought_fedr4.odf" 3.77
    "dom_dreadnought_fedr5.odf" 3.77
    "dom_dreadnought_fedr6.odf" 3.77
    "dom_dreadnought_klir4.odf" 3.77
    "dom_dreadnought_klir5.odf" 3.77
    "dom_dreadnought_klir6.odf" 3.77
    "dom_dreadnought_romr4.odf" 3.77
    "dom_dreadnought_romr5.odf" 3.77
    "dom_dreadnought_romr6.odf" 3.77
    "dom_intercept_destr4.odf" 5.346
    "dom_intercept_destr5.odf" 2.673
    "dom_intercept_destr6.odf" 2.673
    "dom_intercept_dest_romr4.odf" 5.346
    "dom_intercept_dest_romr5.odf" 2.673
    "dom_intercept_dest_romr6.odf" 2.673
    "fed_ambassadorMr6.odf" 5.67
    "fed_ambassadorr6.odf" 5.67
    "fed_intrepidYr6.odf" 5.67
    "fed_intrepidZr6.odf" 5.67
    "fed_intrepid_borr6.odf" 5.67
    "fed_mirandaii.odf" 5.905
    "fed_mirandaiiM.odf" 5.905
    "fed_mirandaiiMr2.odf" 5.905
    "fed_mirandaiiMr3.odf" 5.905
    "fed_mirandaiiMr4.odf" 5.905
    "fed_mirandaiiMr5.odf" 5.905
    "fed_mirandaiiMr6.odf" 5.905
    "fed_mirandaiir2.odf" 5.905
    "fed_mirandaiir3.odf" 5.905
    "fed_mirandaiir4.odf" 5.905
    "fed_mirandaiir5.odf" 5.905
    "fed_mirandaiir6.odf" 5.905
    "fed_monsoonr4.odf" 4.782
    "fed_monsoonr5.odf" 2.31
    "fed_monsoonr6.odf" 3.726
    "fed_monsoonZr4.odf" 4.782
    "fed_monsoonZr5.odf" 2.31
    "fed_monsoonZr6.odf" 3.726
    "fed_monsoon_bor.odf" 4.52
    "fed_monsoon_borr2.odf" 4.52
    "fed_monsoon_borr3.odf" 4.52
    "fed_monsoon_borr4.odf" 6.32
    "fed_monsoon_borr5.odf" 3.315
    "fed_monsoon_borr6.odf" 2.916
    "fed_monsoon_klir4.odf" 4.782
    "fed_monsoon_klir5.odf" 2.31
    "fed_monsoon_klir6.odf" 3.726
    "fed_sovereignr4.odf" 6.69
    "fed_sovereignr5.odf" 5.51
    "fed_sovereignr6.odf" 5.51
    "fed_sovereignYr4.odf" 6.69
    "fed_sovereignYr5.odf" 5.51
    "fed_sovereignYr6.odf" 5.51
    "kli_brelr4.odf" 7.452
    "kli_brelr5.odf" 6.69
    "kli_brelr6.odf" 6.69
    "kli_brelZr4.odf" 7.452
    "kli_brelZr5.odf" 6.69
    "kli_brelZr6.odf" 6.69
    "kli_brel_borr4.odf" 7.452
    "kli_brel_borr5.odf" 6.69
    "kli_brel_borr6.odf" 6.69
    "kli_brel_romr4.odf" 7.452
    "kli_brel_romr5.odf" 6.69
    "kli_brel_romr6.odf" 6.69
    "kli_edjenr4.odf" 7.452
    "kli_edjenr5.odf" 6.69
    "kli_edjenr6.odf" 6.69
    "kli_kvortr6.odf" 6.69
    "kli_kvortZr6.odf" 6.69
    "kli_kvort_fedr6.odf" 6.69
    "rom_generix_dreadr4.odf" 7.723
    "rom_generix_dreadr5.odf" 7.21
    "rom_generix_dreadr6.odf" 7.21
    "rom_generix_dreadYr4.odf" 7.723
    "rom_generix_dreadYr5.odf" 7.21
    "rom_generix_dreadYr6.odf" 7.21
    "rom_generix_dread_klir4.odf" 7.723
    "rom_generix_dread_klir5.odf" 7.21
    "rom_generix_dread_klir6.odf" 7.21
sed 's/damagebase =/damagebase=/g' input.txt |\
    awk '{printf "     %s %s\n",$1,3.1*$2}' |\
    sed 's/.*damagebase=/damagebase =/g'