0

我有一个 GIS 应用程序,它要求 CSV 作为输入,而该 CSV 的值是由另一个 GIS 应用程序以以下 C++ 格式生成的:

class _shape_0
{
objectType="waterbody";
class Arguments
{
    POSITION="[946.58899, 1087.7439, 0]";
    TYPE="01_SaltLake";
    ORIENTATION="45";
};
 };
class _shape_1
{
objectType="vegetation";
class Arguments
{
    POSITION="[962.88275, 1087.9946, 0]";
    TYPE="02_PineWoods";
    ORIENTATION="270";
};
  };
    class _shape_2
 {
objectType="vegetation";
class Arguments
{
    POSITION="[941.5755, 1068.6926, 0]";
    TYPE="03_Wheatcrop";
    ORIENTATION="135";
};

    and so on...

因为输出文件包含数百个项目,所以我想使用一个自动脚本,将POSITION、TYPE 和 ORIENTATION从输出 c++ 文件转换为 CSV,如下所示:

TYPE, POSITION [X, Y, Z], ORIENTATION
03_Wheatcrop, 941.5755, 1068.6926, 0, 135
02_PineWoods, 962.88275, 1087.9946, 0, 270
01_SaltLake, 946.58899, 1087.7439, 0, 45

有没有办法通过powerscript或类似的东西来做到这一点?使用 notepad++ 及其正则表达式对我来说也是一种选择,尽管我更喜欢自动化脚本。

4

1 回答 1

0

一个依赖于固定行顺序的非常快速和肮脏的解决方案很容易。如果记录内部顺序不同,则需要更复杂的方法。

如果记录的顺序发生变化,例如有时TYPE在以前POSITION,有时不是,则必须重新实现解析器。跟踪关键字和一些正则表达式的状态机应该在这种情况下工作。

简单解决方案的想法是读取文件并遍历所有行。如果找到包含的行POSITION,让我们选择它和接下来的两行。删除多余的字符并创建一个格式化的字符串。最后,将所有内容保存在一个文件中。这不使用正确的 CSV 输出,因此如果字段包含需要转义的值,则脚本会中断。如果是这种情况,则需要一种基于自定义对象的更复杂的方法export-csv

$d = get-content  c:\temp\infile.dat # Read the incoming C++ish file
$rows = @() # Empty array for results
$rows += "TYPE, POSITION [X, Y, Z], ORIENTATION" #Header row
for ($i=0; $i -le $d.count -2; ++$i) { # Loop through the data
  if( $d[$i] -match "POSITION" ) { # POSITION element, let's pick it and two next lines
     $pos = $d[$i].Replace('POSITION="[', '').Replace(']";', '').Replace(' ', '') # Remove extra chars
     $typ = $d[$i+1].Replace('TYPE="', '').Replace('";', '').Replace(' ', '')
     $ori = $d[$i+2].Replace('ORIENTATION="', '').Replace('";', '').Replace(' ', '')
     $rows += $("{0}, {1}, {2}" -f $typ, $pos, $ori ) # Add formatted string to array
  } 
}

set-content -path c:\temp\out.csv -value $rows # Write output to a file.
于 2013-02-21T07:27:28.713 回答