使用powershell编辑CSV,但仅意外导出一列

vdzxcuhz  于 5个月前  发布在  Shell
关注(0)|答案(2)|浏览(48)

我试图采取CSV,一个制表符分隔的txt文件,并更改其中一列从'姓氏,第一'到'名字姓氏'.我想我几乎有得到它到另一个程序的正确格式,但我导出的文件只有一列,与我编辑的名称之一.

Import-CSV -Path import.txt  -Delimiter "`t" -Header @("col0", "col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8", "col9", "cal1", "cal2", "cal3", "cal4", "cal5") |
foreach{ 
    $last,$first = $_.col3 -split ", "
    new-object psobject -Property @{name = "$first $last"}
    $_
} |
Export-CSV done.txt -Delimiter "`t" -NoTypeInformation

(Get-Content -Path done.txt ).Replace('"','') | Select-Object -Skip 1 | 
Set-Content -Path done.txt
(gc done.txt) | ? {$_.trim() -ne "" } | set-content done.txt

字符串
我尝试导出到txt或csv.最后两行是更多的格式,但我已经尝试排除它们.也没有标题.所以我添加了它们,并在最后把它们带走.没有添加新对象,它根本不工作.谢谢!

jqjz2hbq

jqjz2hbq1#

  • 直接修改每个输入对象的.col3属性-不需要New-Object
  • 事实上,正是new-object psobject -Property @{name = "$first $last"}发出的对象导致了您的问题:作为 * 第一个 * 输出对象,它 * 锁定了Export-Csv调用的列 *,这意味着只导出了name列。
  • 使用ConvertTo-Csv代替Export-Csv在内存 * 中生成CSV(TSV)数据,作为行流,这允许您通过Select-Object-Skip 1跳过标题行,然后使用Set-Content将剩余行写入输出文件。
Import-CSV -Path import.txt  -Delimiter "`t" -Header col0, col1, col2, col3, col4, col5, col6, col7, col8, col9, cal1, cal2, cal3, cal4, cal5 |
  ForEach-Object{ 
    $last, $first = $_.col3 -split ", "
    $_.col3 = "$first $last"
    $_
  } | 
  ConvertTo-Csv -Delimiter "`t" -NoTypeInformation |
  Select-Object -Skip 1 | 
  Set-Content -Encoding utf8 done.txt

字符串
注意事项:

  • 我已经将-Encoding utf8添加到Set-Content调用中,以提醒您可能希望显式控制字符编码;假设Set-Content默认使用系统的活动遗留ANSI代码页;请注意,-Encoding utf8总是在Windows PowerShell中生成UTF-8文件 * 和BOM*。
  • Windows PowerShell 中,您无法控制输出CSV(TSV)数据中的字段是否被双引号引用-它们都是,但对于行为良好的CSV / TSV读取器来说,这不应该有什么区别。
  • PowerShell (Core) 7+中:
  • 您确实可以通过-UseQuotes-QuoteFields参数控制ConvertTo-CsvExport-Csv的引用行为。
  • 此外,这两个小插件现在支持-NoHeader开关,以避免发出/写入标题行,并且不再需要使用-NoTypeInformation
  • 此外,(无BOM)UTF-8现在是 * 一致的 * 默认编码。如果需要,您仍然可以使用-Encoding utf8BOM请求BOM

因此,在 PowerShell(Core)7+ 中,代码可以简化为以下内容:

# PS 7+ only
Import-CSV -Path import.txt  -Delimiter "`t" -Header col0, col1, col2, col3, col4, col5, col6, col7, col8, col9, cal1, cal2, cal3, cal4, cal5 |
  ForEach-Object{ 
    $last, $first = $_.col3 -split ", "
    $_.col3 = "$first $last"
    $_
  } | 
  Export-Csv done.txt -Delimiter "`t" -UseQuotes Never -NoHeader


上面的代码省略了字段中的双引号,并创建了一个无BOM的UTF-8输出文件。

uxh89sit

uxh89sit2#

如果有一个示例源和一个示例目标字符串,我会很高兴,但我猜您需要这样的东西

Get-Content -Path import.txt | foreach {
     $tmp = $_ -split "\t";
     $tmp[3] = $tmp[3] -replace "^([^,]*), ?(.*)",'$2 $1';
     $tmp -join "`t"
 } | Set-Content -Path import.txt

字符串
它逐行读取文本文件。按制表符拆分字符串。更改第四列,将逗号前的第一部分作为第二部分(后面可能有一个空格)。第二部分现在变成第一部分,后面跟着一个空格和第一部分。现在所有字符串都通过制表符重新连接在一起。

相关问题