Найти текстовые данные в CSV-файле Numeri c Столбцы в Powershell - PullRequest
1 голос
/ 04 февраля 2020

Я очень новичок в PowerShell. Я пытаюсь проверить мой CSV-файл, выяснив, есть ли какое-либо текстовое значение в моих полях нумерации c. Я могу определить с помощью столбцов цифры c.

Это мои исходные данные, подобные этим

ColA      ColB    ColC      ColD
23        23       ff       100
2.30E+01  34    2.40E+01    23
df        33      ss        df
34        35      36       37

Мне нужно вывести что-то вроде этого (только текстовые значения, если они найдены в любом столбце)

ColA         ColC       ColD
2.30E+01      ff        df
df           2.40E+01   
              ss    

Я пытался некоторый код, но не получая никаких результатов, получайте только какой-то вывод, как в

System.Object[]


---------------                                                                                                                                                                      
                                                        xxx fff' ddd 3.54E+03 

                                                                                                ...

Это то, что я пытался

#
cls

function Is-Numeric ($Value) {
    return $Value -match "^[\d\.]+$"
}

$arrResult = @()
$arraycol = @()

$FileCol = @("ColA","ColB","ColC","ColD")

$dif_file_path = "C:\Users\$env:username\desktop\f2.csv"

#Importing CSVs

$dif_file = Import-Csv -Path $dif_file_path -Delimiter ","

############## Test Datatype (Is-Numeric)##########

 foreach($col in $FileCol)
  {
  foreach ($line in $dif_file) {

    $val = $line.$col

     $isnum = Is-Numeric($val)

    if ($isnum -eq $false) {
   $arrResult +=  $line.$col
   $arraycol += $col

    }
 }
 }
   [pscustomobject]@{$arraycol = "$arrResult"}| out-file "C:\Users\$env:username\Desktop\Errors1.csv" 
####################

Может кто-нибудь направить меня в правильном направлении? Спасибо

Ответы [ 4 ]

2 голосов
/ 04 февраля 2020

Вы можете попробовать что-то вроде этого,

function Is-Numeric ($Value) {
    return $Value -match "^[\d\.]+$"
}

$dif_file_path = "C:\Users\$env:username\desktop\f2.csv"

#Importing CSVs

$dif_file = Import-Csv -Path $dif_file_path -Delimiter ","

#$columns = $dif_file | Get-member -MemberType 'NoteProperty' | Select-Object -ExpandProperty 'Name'
# Use this to specify certain columns
$columns = "ColB", "ColC", "ColD"

foreach($row in $dif_file) {
  foreach ($col in $columns) { 
    if ($col -in $columns) {
      if (!(Is-Numeric $row.$col)) { 
        $row.$col = "" 
      }
    }
  } 
} 

$dif_file | Export-Csv C:\temp\formatted.txt 
  1. Искать имена столбцов, как вы go
  2. Искать значения каждого столбца в каждой строке и, если это не является цифрой c, измените на ""
  3. Экспортированный обновленный файл.
1 голос
/ 04 февраля 2020

Я думаю, что отсутствие отображения столбцов без данных создает проблему здесь. Вы можете сделать следующее:

$csv = Import-Csv "C:\Users\$env:username\desktop\f2.csv"
$finalprops = [collections.generic.list[string]]@()

$out = foreach ($line in $csv) {
    $props = $line.psobject.properties | Where {$_.Value -notmatch '^[\d\.]+$'} |
        Select-Object -Expand Name
    $props | Where {$_ -notin $finalprops} | Foreach-Object { $finalprops.add($_) }
    if ($props) {
        $line | Select $props
    }
$out | Select-Object ($finalprops | Sort)

Учитывая характер Format-Table или табличного вывода, вы видите только свойства первого объекта в коллекции. Поэтому, если для object1 есть только ColA, а для object2 - ColA и ColB, вы увидите только ColA.

0 голосов
/ 05 февраля 2020

Порядок вывода, который вы хотите, сильно отличается от входного CSV; вы отслеживаете неверные текстовые данные не по первому вхождению, а по порядку столбцов , что требует дополнительных действий.

содержимое файла test.csv:

ColA,ColB,ColC,ColD
23,23,ff,100
2.30E+01,34,2.40E+01,23
df,33,ss,df
34,35,36,37

Пример кода, проверенного на соответствие вашему описанию:

$csvIn = Import-Csv "$PSScriptRoot\test.csv";

# create working data set with headers in same order as input file
$data  = [ordered]@{};
$csvIn[0].PSObject.Properties | foreach {
    $data.Add($_.Name, (New-Object System.Collections.ArrayList));
};

# add fields with text data
$csvIn | foreach {
    $_.PSObject.Properties | foreach {
        if ($_.Value -notmatch '^-?[\d\.]+$') {
            $null = $data[$_.Name].Add($_.Value);
        }
    }
}

$removes  = @(); # remove `good` columns with numeric data
$rowCount = 0;   # column with most bad values
$data.GetEnumerator() | foreach { 
    $badCount = $_.Value.Count;
    if ($badCount -eq 0) { $removes  += $_.Key; }
    if ($badCount -gt $rowCount) { $rowCount = $badCount; }
}
$removes | foreach { $data.Remove($_); }

0..($rowCount - 1) | foreach {
    $h = [ordered]@{};
    foreach ($key in $data.Keys) {
        $h.Add($key, $data[$key][$_]);
    }
    [PSCustomObject]$h;
} | 
Export-Csv -NoTypeInformation -Path "$PSScriptRoot\text-data.csv";

содержимое выходного файла:

"ColA","ColC","ColD"
"2.30E+01","ff","df"
"df","2.40E+01",
,"ss",
0 голосов
/ 04 февраля 2020

@ Jawad, наконец-то я попробовал

function Is-Numeric ($Value) {
    return $Value -match "^[\d\.]+$"
}
$arrResult = @()
$columns = "ColA","ColB","ColC","ColD"
$dif_file_path = "C:\Users\$env:username\desktop\f1.csv" 
$dif_file = Import-Csv -Path $dif_file_path -Delimiter "," |select  $columns
$columns = $dif_file | Get-member -MemberType 'NoteProperty' | Select-Object -ExpandProperty 'Name'
foreach($row in $dif_file) {
  foreach ($col in $columns) { 
  $val = $row.$col
  $isnum = Is-Numeric($val)
       if ($isnum -eq $false) { 
        $arrResult += $col+ " " +$row.$col
      }}} 
 $arrResult | out-file "C:\Users\$env:username\desktop\Errordata.csv"

Я получил правильный результат в моем файле, порядок очень неоднозначный, как

ColA ss
ColB 5.74E+03
ColA ss
ColC rrr
ColB 3.54E+03
ColD ss
ColB 8.31E+03
ColD cc

Есть идеи, чтобы получить правильный формат? спасибо Примечание: с вашим предложенным кодом я получаю полный исходный файл со всеми данными, а не с указанными c данными об ошибках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...