powershell脚本更改文本文件

时间:2016-02-20 10:38:28

标签: powershell

您知道如何使用powershell将列DocumentNo移动到最后一列吗?

| D|Ref.Doc.  |Row|DocumentNo     |CoCd|Pstng Date
| W|5007534739|  1|65713191       |STCD|01/17/2016
| W|5007534739|  1|65713191       |STCD|01/17/2016
| W|5007534739|  1|65713191       |STCD|01/17/2016

预期输出

| D|Ref.Doc.  |Row|CoCd|Pstng Date|DocumentNo       
| W|5007534739|  1|STCD|01/17/2016|65713191       
| W|5007534739|  1|STCD|01/17/2016|65713191       
| W|5007534739|  1|STCD|01/17/2016|65713191  

这是我尝试过的命令

(get-content $file -ReadCount 0) |
foreach  {
'{0}|{1}|{2}|{3}|{5}|{6}|{4}' -f $_.split('|')
} | Set-Content $file2

代码工作正常,但万一DocumentNo将管道作为数据包含,如何处理?

2 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

$delimiter = "|"
$data = Get-Content "c:\tmp\test.csv";
$newCsv= ($data|Foreach-object { ($_ -split $delimiter)[@(0..3;5;6;4)] -join  $delimiter})

# Set the new-ordered column content to the new-file

$newCsv|Set-Content C:\tmp\test2.csv

如果您想将所有这些都放在一行中,您可以执行以下操作:

Get-Content "c:\tmp\test.csv"|Foreach-object { ($_ -split '|')[@(0..3;5;6;4)] -join '|'}|Set-Content C:\tmp\test2.csv

请注意,如果您将get-content作为管道的一部分,则不能使用set-content,因为该文件将是打开的,并且不能将其作为流的一部分替换它的内容。

您必须使用第一种方法(首先阅读内容,然后将其传递给流)或将内容设置为不同的文件。

答案 1 :(得分:2)

如果在数据本身内部使用分隔符,它会破坏csv。我看到数据是固定宽度的(尽管长度和索引可能会因文件而异),所以我会采用不同的方法。

  1. 找到DocumentNo-column的位置。您可以使用正则表达式(https://regex101.com/r/pH2oL9/1)。我使用[Regex]::Match()因为它返回匹配(列)的index(起始位置)和length(字符数)。
  2. 创建一个正则表达式,在每行上查找相同位置和长度的内容。它为"","内容","""通过计算"任何角色"直到我决定的开始位置,然后是列的长度,然后"直到行结束"。我在正则表达式中使用子表达式$()来插入步骤2中的indexlength,因为它们对于每个文件可能都不相同。
  3. -replace与生成的正则表达式一起使用来修改每一行的文本(因为$text是一个数组)。 -replace找到这些组,并使用$1$3$2我可以说我希望在结果中插入哪些组。 (https://regex101.com/r/vE6vO9/1
  4. 解决方案:

    #Sample text
    $text = Get-Content .\Test.txt
    
    #Analyze header (find DocumentNo placement in fixed-width file) and create regex
    $regex = [regex]::Match($text[0], '\|DocumentNo\s+') | ForEach-Object { "^(.{$($_.Index)})(.{$($_.Length)})(.*)$" }
    
    #Modify text
    $text -replace $regex, '$1$3$2' | Set-Content .\TestOut.txt
    

    TestOut.txt

    | D|Ref.Doc.  |Row|CoCd|Pstng Date|DocumentNo     
    | W|5007534739|  1|STCD|01/17/2016|65713191       
    | W|5007534739|  1|STCD|01/17/2016|65713191       
    | W|5007534739|  1|STCD|01/17/2016|65713191       
    

    您可能希望修剪尾随空格。请使用Trim()

    $text -replace $regex, '$1$3$2' | ForEach-Object { $_.Trim() } | Set-Content .\TestOut.txt