我有一个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 ++及其正则表达式也是我的选择,虽然我更喜欢自动脚本。
答案 0 :(得分: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.