如何从 powershell 中的多个 csv 文件中删除特定行?
How to delete specific rows from multiple csv files in powershell?
您好,我正在寻找一种从多个 csv 文件中删除第二行和最后一行的有效方法吗?我在一个目录中有大约 5000 个文件。
下面的代码将删除第一行。如果我使用参数 -skip 2。它将跳过前两行,但我需要保留第一行并删除第二行和最后一行。我也不确定 get-content set-content 是否是获取如此大量文件的正确方法。
foreach ($file in gci *.csv ){
(gc $file) | Select-Object -Skip 1 | set-content $file
}
也许不是最好的方法,但您可以使用 -Index
并计算所需的行。
foreach ($file in gci *.csv ){
$data = gc $file
$data | Select-Object -Index (,0 + (2..($data.Count - 2))) | set-content $file
}
索引,对于数组,从 0 开始,所以我们取那个并跳过记录 1。之后我们只取剩下的减去最后一个。 -Index
采用整数数组,因此我们创建一个值为 0 的单个元素数组,并附加索引从 2 到文件末尾减去最后一个(这是 -2
的来源,因为 .Count
从 1) 开始。
你很接近,我只是通过你代码中的 Where 子句来跳过每个文件中的第 1 项和第 -1 项。像这样:
(gci *.csv )|ForEach{
$file = $_
$contents = gc $file
$contents | Where{$_ -ne $contents[1] -and $_ -ne $contents[-1]} | out-file $file.fullname -force
}
我执行了 ForEach 内联以确保 GCI 完成并且在您尝试执行 Out-File 时没有保持任何打开状态
编辑: 我刚刚意识到我的代码有一个潜在的缺陷,如果你在第 2 行或最后一行有重复的行,这些行也会被删除。我写这篇文章时假设您有类似以下内容的内容需要清理:
Col1,Col2,Col3,Col4
---- ---- ---- ----
Data,data,data,data
data,data,data,data
Log Created: 02/04/2015
您想删除 --- 行和日志最后创建注释的位置。
Edit2: 更好的解决方案可能是获取文件的内容,输出第一行,然后输出第 3 行到最后(负 1 行)和将其附加到同一个文件。类似于:
(gci *.csv )|ForEach{
$Path = $_.FullName
$content = gc $Path
$content|select -first 1|Out-File $Path -force
$content[2..($content.count-2)]|Out-File $Path -Append
}
简单说一下表演。我使用@TheMadTechnician 方法获取内容并比较了 3 种不同的输出编写方法。我为每个测试使用了 100 个 1MB 的输入文件。以下是结果:
使用Out-File覆盖内容耗时1分32秒
dir *.txt | %{
$content = gc $_.FullName
$content | select -First 1 | Out-File $_.FullName -Force
$content[2..($content.count -2)]|Out-File $_.FullName -Append
}
使用 Set-Content 覆盖内容用了 37 秒。
dir *.txt | %{
$content = gc $_.FullName
$output = @($content | select -First 1 )
$output += $content[2..($content.count -2)]
$output | Set-Content $_.FullName -Force
}
使用 StreamWriter 覆盖内容用了 31 秒。
dir *.txt | %{
$content = gc $_.FullName
$output = @($content | select -First 1 )
$output += $content[2..($content.count -2)]
$sw = New-Object System.IO.StreamWriter($_.FullName,$false)
$output | %{$sw.WriteLine($_)}
$sw.close()
}
您可能想针对您的特定情况研究这些不同的方法,但我总是发现 Out-File 比 Set-Content 或 StreamWriter 慢得多。
您好,我正在寻找一种从多个 csv 文件中删除第二行和最后一行的有效方法吗?我在一个目录中有大约 5000 个文件。 下面的代码将删除第一行。如果我使用参数 -skip 2。它将跳过前两行,但我需要保留第一行并删除第二行和最后一行。我也不确定 get-content set-content 是否是获取如此大量文件的正确方法。
foreach ($file in gci *.csv ){
(gc $file) | Select-Object -Skip 1 | set-content $file
}
也许不是最好的方法,但您可以使用 -Index
并计算所需的行。
foreach ($file in gci *.csv ){
$data = gc $file
$data | Select-Object -Index (,0 + (2..($data.Count - 2))) | set-content $file
}
索引,对于数组,从 0 开始,所以我们取那个并跳过记录 1。之后我们只取剩下的减去最后一个。 -Index
采用整数数组,因此我们创建一个值为 0 的单个元素数组,并附加索引从 2 到文件末尾减去最后一个(这是 -2
的来源,因为 .Count
从 1) 开始。
你很接近,我只是通过你代码中的 Where 子句来跳过每个文件中的第 1 项和第 -1 项。像这样:
(gci *.csv )|ForEach{
$file = $_
$contents = gc $file
$contents | Where{$_ -ne $contents[1] -and $_ -ne $contents[-1]} | out-file $file.fullname -force
}
我执行了 ForEach 内联以确保 GCI 完成并且在您尝试执行 Out-File 时没有保持任何打开状态
编辑: 我刚刚意识到我的代码有一个潜在的缺陷,如果你在第 2 行或最后一行有重复的行,这些行也会被删除。我写这篇文章时假设您有类似以下内容的内容需要清理:
Col1,Col2,Col3,Col4
---- ---- ---- ----
Data,data,data,data
data,data,data,data
Log Created: 02/04/2015
您想删除 --- 行和日志最后创建注释的位置。
Edit2: 更好的解决方案可能是获取文件的内容,输出第一行,然后输出第 3 行到最后(负 1 行)和将其附加到同一个文件。类似于:
(gci *.csv )|ForEach{
$Path = $_.FullName
$content = gc $Path
$content|select -first 1|Out-File $Path -force
$content[2..($content.count-2)]|Out-File $Path -Append
}
简单说一下表演。我使用@TheMadTechnician 方法获取内容并比较了 3 种不同的输出编写方法。我为每个测试使用了 100 个 1MB 的输入文件。以下是结果:
使用Out-File覆盖内容耗时1分32秒
dir *.txt | %{
$content = gc $_.FullName
$content | select -First 1 | Out-File $_.FullName -Force
$content[2..($content.count -2)]|Out-File $_.FullName -Append
}
使用 Set-Content 覆盖内容用了 37 秒。
dir *.txt | %{
$content = gc $_.FullName
$output = @($content | select -First 1 )
$output += $content[2..($content.count -2)]
$output | Set-Content $_.FullName -Force
}
使用 StreamWriter 覆盖内容用了 31 秒。
dir *.txt | %{
$content = gc $_.FullName
$output = @($content | select -First 1 )
$output += $content[2..($content.count -2)]
$sw = New-Object System.IO.StreamWriter($_.FullName,$false)
$output | %{$sw.WriteLine($_)}
$sw.close()
}
您可能想针对您的特定情况研究这些不同的方法,但我总是发现 Out-File 比 Set-Content 或 StreamWriter 慢得多。