【问题标题】:Replace blank characters from a file line by line逐行替换文件中的空白字符
【发布时间】:2016-04-08 04:48:06
【问题描述】:

我希望能够从 CSV 文件中找到所有空白字符,如果在一行上找到空白字符,则应该出现在屏幕上,并且应该询问我是否要保留包含该白色的整行空间或删除它。

假设目录是C:\Cr\Powershell\test。里面有一个CSV文件abc.csv

尝试这样做,但在 PowerShell ISE 中无法识别 $_.PSObject.Properties

$csv = Import-Csv C:\Cr\Powershell\test\*.csv | Foreach-Object {
   $_.PSObject.Properties | Foreach-Object {$_.Value = $_.Value.Trim()}  
}

对于没有包含更多代码以及迄今为止我尝试过的更多内容,我深表歉意,但自从我刚开始以来,它们都是愚蠢的尝试。

This 看起来很有帮助,但我不知道如何根据我的问题调整它。

【问题讨论】:

  • 您的问题到底是什么?如何提示用户输入?如何替换空白字符?或者如何逐行处理文件?这是三个不同的问题,你不应该混淆它们。
  • 如何在逐行处理并等待用户输入每一行时替换空白字符。对不起,如果我把它们混在一起了,但即使我问了 3 个不能解决我问题的不同问题。我需要三合一
  • @CM2K 你想删除整行还是只替换空白字符
  • 鉴于你现在拥有的,这基本上意味着为你编写脚本。
  • @Paul 如果该行上有一个空白字符,则删除整行。但是如果我应该这样做,应该在屏幕上提示。因为有些台词我必须保留

标签: csv powershell powershell-3.0 powershell-ise


【解决方案1】:

好吧,你去吧:

$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Retain line."

$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Delete line."

$n = @()

$f = Get-Content .\test.csv  
foreach($item in $f) {

if($item -like "* *"){ 
    $res = $host.ui.PromptForChoice("Title", "want to keep this line? `n $item", [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no), 0)

    switch ($res) 
    {
        0 {$n+=$item}
        1 {}
    }


} else {
    $n+=$item
}

}

$n | Set-Content .\test.csv

如果您有任何问题,请在 cmets 中发帖,我会解释

【讨论】:

  • 哦,谢谢!我会马上测试它。我期待了解有关 PowerShell 的更多信息
  • 它有效。谢谢!我不完全明白你是如何用空格显示行的部分。 $n = @() 到 n 被附加到 if 子句中的项目是。但是如何将一条线设置为一个项目。我在看foreach($item in $f),但我不完全明白
  • @CM2K 该行正在使用$item 变量显示在对话框中,$item 变量确实是由foreach 语句设置的(“item”当然只是一个任意的名字,可以是你想要的任何东西)。基本上,如果您使用 get-content 每行将是一个数组项,foreach 循环遍历数组并始终为当前项分配您在语句开头使用的变量名,在这种情况下为$item
  • 很好的解决方案。从第一天开始我就不可能写这个,我只有sql经验,但现在我明白了,再次感谢!
【解决方案2】:

Get-Content 可能是比Import-Csv 更好的方法,因为这将允许您检查整行的空格,而不必检查每个单独的字段。对于全自动处理,您只需使用 Where-Object 过滤器从输出中删除不匹配的行:

Get-Content 'C:\CrPowershell\test\input.csv' |
  Where-Object { $_ -notlike '* *' } |
  Set-Content 'C:\CrPowershell\test\output.csv'

但是,由于您要提示包含空格的每一行,您需要一个 ForEach-Object(或类似构造)和一个嵌套条件,如下所示:

Get-Content 'C:\CrPowershell\test\input.csv' | ForEach-Object {
  if ($_ -notlike '* *') { $_ }
} | Set-Content 'C:\CrPowershell\test\output.csv'

提示用户输入的最简单方法是Read-Host

$answer = Read-Host -Prompt 'Message'
if ($answer -eq 'y') {
  # do one thing
} else {
  # do another
}

在您的特定情况下,您可能会对任何匹配的行执行类似的操作:

$anwser = Read-Host "$_`nKeep the line? [y/n] "
if ($answer -ne 'n') { $_ }

上面检查答案是否不是 n 以做出有意识的决定。

提示用户输入的其他方式是choice.exe(它的另一个优点是允许超时和默认答案):

choice.exe /c YN /d N /t 10 /m "$_`nKeep the line"
if ($LastExitCode -ne 2) { $_ }

host UI

$title   = $_
$message = 'Keep the line?'

$yes = New-Object Management.Automation.Host.ChoiceDescription '&Yes'
$no  = New-Object Management.Automation.Host.ChoiceDescription '&No'

$options = [Management.Automation.Host.ChoiceDescription[]]($yes, $no)

$answer = $Host.UI.PromptForChoice($title, $message, $options, 1)
if ($answer -ne 1) { $_ }

我将把它作为一个练习,让您将您选择的任何提示例程与其余代码集成。

【讨论】:

  • 感谢您的明确解释。我今天从中学到了很多。感谢您的宝贵时间
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 2015-01-06
  • 1970-01-01
  • 2020-03-29
相关资源
最近更新 更多