簡體   English   中英

在CSV文件上運行PowerShell-根據字符串查找字符串

[英]PowerShell on CSV file - looking for string depending on string

我需要有關在CSV文件上進行PowerShell編程的幫助。

我進行了一些搜索,但找不到所需的內容(或者我不知道技術術語)。 基本上,我有一個包含大量數據(或多或少38列x 350.000行)的Excel工作簿,並且有幾個公式需要幾個小時才能計算出來。

我首先想知道,與Excel相比,PowerShell是否可以加快計算速度。 實際上,占用我大部分時間的計算並不那么復雜(至少乍一看)。 我的數據或多或少是這樣構造的:

Ref      Title
-----    --------------------------
A/001    "free_text"
A/002    "free_text A/001 free_text"
...      ...
A/005    "free_text A/004 free_text"
A/006    "free_text"
B/001    "free_text" 
B/002    "free_text"
C/001    "free_text"
C/002    "free_text"
...
C/050    "free_text C/047 free_text"
...      ...
C/103    "free_text"
D/001    "free_text"
D/002    "free_text D/001 free_text"
...      ....

基本上數據如下:

  1. Ref字段包含唯一值,格式為{letter}/{incremental value}
  2. 在某些行中,“ 標題”字段可以調用“ 引用”數據之一。 例如,在第2行中, 標題要求使用A / 001 Ref 在最后一行, 標題要求D / 001 Ref等。
  3. 沒有邏輯模式定義何時可以在標題中調用此引用。 這是隨機的。

但是,我100%確信以下幾點:

  1. 標題中調用的Ref始終屬於同一{letter}塊。 例如:“ 標題”字段中的字符串“ C / 047”只能在Ref {letter}為C的塊中找到。
  2. 標題中 引用的Ref將始終位於其引用的Ref的 “之后”(或較低的行)中。 換句話說,我不能使用以下格式的行:

    \n 參考標題\n ------------ -------------------------------------- ---\n {jetter / i} {free_text {letter / j} free_text}且j <i\n

    →這是不可能的。
    →j總是> i

我已在Excel中使用這些特征來最大程度地減少查找數組。 但是計算所有內容仍需要一個小時。

因此,我研究了PowerShell,並開始使用CSV進行“播放”,並使用ForEach-Object循環,希望得到更快的結果。 到目前為止,我基本上結束了對CSV文件的兩次循環。

$CSV1 = myfile.csv
$CSV2 = myfile.csv

$CSV1 | ForEach-Object {
    # find Title
    $TitSearch = $_.$Ref
    $CSV2 | ForEach-Object {
        if ($_.$Title -eq $TitSearch) {
            myinstructions
        }
    }
}

它可以工作,但是真的很長。 因此,我嘗試了以下方法,而不是使用$CSV2 | ForEach... $CSV2 | ForEach...

$CSV | where {$_.$Title -eq $TitleSearch} | % $Ref

無論哪種情況,它都太長並且根本沒有效率。 此外,使用這兩種解決方案時,我沒有使用上述特征,因為它們可能會減少查找數組,並且如上所述,看來我最終在CSV文件中從開始到結束都循環了兩次。

問題:

  1. 有更精簡的方法嗎?
  2. 我在浪費時間在PowerShell上嗎?
  3. 我雖然要為每個Ref {letter}塊創建1個文件(A塊1個文件,B 1個文件等等)。 但是我有大約50.000塊要創建。 或一個一個地創建它們,進行分析,將結果放入一個新文件中,然后刪除它們。 這樣會更快嗎?

注意:這是工作,供其他同事使用,而Excel和PowerShell實際上是我們可能會使用的唯一軟件。 我知道VBA,但還可以...最后,我很好奇如何以及是否可以使用PowerShell以簡單的方式解決此問題。

據我所知,您的基本算法進行了N ^ 2次迭代(約1,200億)。 有一種提高效率的標准方法-您需要先構建一個哈希表。 Hashtable是鍵/值存儲,並且查找幾乎是瞬時的,因此算法的時間復雜度將變為〜N。 Powershell為此提供了內置數據類型。 在您的情況下,鍵將是ref,並且值是單元格數據數組(假設您的表像是smth一樣:ref,title,col1,...,colN)

$hash = @{}
foreach($row in $table} {$hash.Add($row.ref, @($row.title, $row.col1, ...)}
#it will take 350K steps to generate it
#then you can iterate over it again
foreach($key in $hash.Keys) { 
 $key # access current ref
 $rowData = $hash.$key # access to current row elements (by index)
 $refRowData = $hash[$rowData[$j]] # lookup from other rows, assuming lookup reference is in some column
}

因此,解決時間問題是一個普遍的想法。 老實說,我不認為您需要重新創建輪子並自己編寫代碼。 您需要一個關系數據庫。 既然您具有Excel,那么您也應該擁有MS ACCESS。 只需將您的數據導入那里,使ref和title成為索引,那么您要做的就是自我聯接。 MS Access很爛,但是我敢肯定它可以處理350K行。 理想情況下,您需要在某些公司MSSQL服務器上獲得一個數據庫(打開票證,與您的經理交談,等等)。 它將以秒為單位計算所有內容,然后您也可以將輸出鏈接到電子表格。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM