2012-03-06 4 views
0

指定した日付より大きい日付を含むすべての行を削除する必要があるCSVファイルがあります。 PowerShellでこれをどうすればできますか?PowerShellを使用してファイルから日付ベースの行を削除する方法

ところで:ここでは、日付の形式である:2011年9月29日

例:私は2011年9月29日より大きい日付を含むすべての行を削除したいと思います。これはあなたがCSV形式であると仮定

+0

あなたはサンプルファイルや抜粋を持っていますか?日付は常にすべてのファイルの同じ列にありますか、それとも行内のどこにあってもかまいませんか? – Joey

+0

日付は常に2番目の列に表示されます。次の行の抜粋です: '000329 | 09/30/2011 | BLNDCOM |アイテム||||||||||||| 1 || 1 || |||||| 3 | 1 || 2 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | 1 | 4 | 1 | 1 | 1 || 1 | 3 |||| 2 ||| 1 ||||||| 2 |||||||| – Keith

+0

実際、 CSVファイルを詳しく調べると、パイプで区切られた行全体が最初の列にスクロールされているように見えます。 – Keith

答えて

2
foreach ($file in gci *.csv){ 
    (gc $file) | 
    ? {[datetime]$_.split('|')[1] -lt '09/29/2011' 
    } | set-content $file 

} 

+0

ありがとう、mjolinor!私はあなたの素敵な - きちんとしたクリーンなコードが好きです。少ないほうがいいです。 ;-)それは完璧に働いた! – Keith

+0

+1私はそれがファイルの内容を置き換えるセット内容とremenberを使用するための+1! –

+0

@mjolinor - CSVファイルを '指定された日付'以上の日付と1週間の増分に基づいて分割するには、コードをどのように変更しますか?あなたのコードは、09/29/2011より前のすべての日付を含む行を含むCSVファイルを作成するのに役立ちますが、今度は '> = 'の日付を持つ行を含む追加のCSVファイルを作成する必要があり、各CSVファイルには1週間の範囲の日付。前もって感謝します! – Keith

0

は、新しい洗浄CSVファイルを作成する必要が

col1,date,col3 
aaaaa,05/05/2010,rwer 
bdfdfg,06/29/2011,reewr 
dsfsdf,08/05/2012,dsfsd 

次のように実行します。

import-csv .\myoriginal.csv -delimiter '|' | ? { [datetime]$_.date -ge [datetime]"09/29/2011"} | Export-Csv -NoTypeInformation -Path .\mycleaned.csv -delimiter '|' 

は、あなたは

と、元のCSVを削除することができます
remove-item .\myoriginal.csv 
+0

これは、すべての種類の行を削除しますが、必要な行だけを削除する可能性があります。 CSVにタイプ情報がない場合は、文字列だけが得られることに注意してください。そしてあなたはそこで文字列を比較しています。もし彼らが問題ないだろうが、このようにしていれば、ちょうど '10/02/2009'と一緒に行をつけて見なさい;-) – Joey

+0

Hmm ..上記のスクリプトを実行すると私のものすべてが削除されるCSVファイル、または少なくともExport-Csvファイルにはデータが含まれていません。以下はCSVファイルの文字列(行)の例です: '000329 | 10/01/2011 | BLNDCOM | Items' – Keith

+0

@Joey。ありがとう。私はpiped値と "date"を[datetime]にキャストすることで修正しました。 –

1

[OK]を、とにかく、その行の日付のように見えるだけで一つのことがあるように思えるので、私たちはただそのためにフィルタリングすることができます。

Get-ChildItem *.csv | # adapt if necessary 
    ForEach-Object { 
    (Get-Content $_) | # the parentheses are important so the entire file is read at once 
     Where-Object { # now we process the file line by line 
     # find the date      ↓ suppress the boolean output 
     $_ -match '\|(\d{2}/\d{2}/\d{4})\|' | Out-Null 

     # this only works if every line contains a date. Hopefully it does. 
     $date = [DateTime]($Matches[1]) 

     # Finally the comparison we wanted in the first place 
     # This is the condition for all lines that are *retained* (hence less than) 
     $date -lt '09/29/2011' 
     } | Out-File $_ # use -Encoding ASCII/UTF8/Unicode depending on your needs. 
         # Maybe ASCII is enough 
    } 

または短い:

gci *.csv | % { 
    (gc $_) | 
    ? { 
     $null = $_ -match '\|(\d{2}/\d{2}/\d{4})\|' 
     [DateTime]$Matches[1] -lt '09/29/2011' 
    } | 
    Out-File $_ 
} 
+0

ありがとう、ジョーイ。上記のコードを使ってみましたが、次のようなエラーが出ました: '演算子 '-match'の引数が間違っています:\ {(\ d {2}/\ d {2}/\ d {4} \) - 十分ではない) + $ null = $ _ -match <<<< '\ |(\ d {2}/\ d {2}/\ d {4} \)|' + CategoryInfo:InvalidOperation:(:) []、RuntimeException + FullyQualifiedErrorId:BadOperatorArgument nullを "System.DateTime"の型に変換できません。 + [DateTime] $一致[<<<< 1] -lt '09/29/2011 ' + CategoryInfo:NotSpecified:(:) []、RuntimeException + FullyQualifiedErrorId:RuntimeException' – Keith

+0

はい、申し訳ありません、誤植。私は間違ったキャラクターを逃れました。 – Joey

+0

ありがとうJoey!あなたの変更されたコードがうまくいったようです。私が2 MBのCSVファイルでそれを実行したとき、それは2749行を予想どおりに取り除いた。しかし、奇妙なのは、CSVファイルが今大きくなっていることです(3.17MB)。それがなぜであるかわからない。注:私もmjolinorのコードを実行し、同じ結果を得ました(2749行が削除されました)が、CSVファイルは1.85 MBです。私はあなたのコードとmjolinorのコードからのCSV出力を比較し、ファイルは同一である(サイズを除く)。奇妙な。 :-) – Keith

1

私はオーバー明瞭さを好みます簡潔:それは、パイプで区切られたファイルだと仮定すると、

param (
    [parameter(Mandatory = $true)] [string] $csvFileName, 
    [parameter(Mandatory = $true)] [datetime] $date 
) 

try 
{ 
    $Error.Clear() 

    if (!(Test-Path $csvFileName)) 
     { throw "Could not find file $csvFileName" } 

    $newContent = Get-Content $csvFileName | ?{ 
     ([regex]::matches($_, "[0-9]{2}/[0-9]{2}/[0-9]{4}") | %{[DateTime] $_.value -lt $date}) 
    } 

    $newContent | Set-Content $csvFileName 
} 

catch 
{ 
    Write-Host "$($MyInvocation.InvocationName): $_" 
} 
+1

ユージンの斧には注意してください。これは、Excelのファイル内のどこかの行の* ALL *日付と一致します。 * 1つの列だけをフィルタリングしたい場合は、正規表現を微調整する必要があります。 –

-1

私はあなたのためにスクリプトを書いています。すべての行を削除するには、指定したパターンがあります。 次のようなスクリプトを実行する必要があります。

myscruipt.sh YOURDATYE YOURCSVFILE 

myscript.sh:

#!/bin/bash 
    declare -a num 
    num=`egrep -n "$1" yahoo_ab.csv |awk 'BEGIN{FS=":";}{for (i=0 ; i<NF ; i++) print $1; } '` 
    while true; do 
     for i in $num ; do 
      sed -i "$i d" $2 ; 
     done; 
     egrep $1 $2; 
     if [ $? = 1 ]; then break; fi; 
    done; 
関連する問題