Слишком много утверждений if else

#powershell

#powershell

Вопрос:

Я пытаюсь проверить, существует ли строка «03-22-2019» (или нет, и показать результат в выходных данных), файл имеет вид «.sql» или «.txt» .

выполнение  разработка process.sql 
вставить.sql 
productionlogs.txt 
восстановить.sql 
rebuild.txt

Я пытаюсь использовать приведенный ниже код, но у меня получилось слишком много if else . Указанный выше путь к файлу хранится в $paths переменной. Мне нужно разделить путь с помощью «» и получить последнюю часть пути, чтобы сделать что-то еще.

 if ($paths -like "*.sql") {
    if ($paths.Contains("")) {
        $last = $paths.Split("")[-1] #get the last part of the path
        $result = "03-22-2019" #get this date from some where else
        if ($result) {
            #check if pattern string exists in that file.
            $SEL = Select-String -Path <path location> -Pattern $result
            if ($SEL -ne $null) {
                Write-Host "`n $last Contains Matching date "
            } else {
                Write-Host "`n $last Does not Contains date"
            }
        } else {
            Write-Host "`ndate field is blank"
        }
    } else {
        $result = "03-22-2019" #get this date from some where else
        if ($result) {
            #check if pattern string exists in that file.
            $SEL = Select-String -Path <path location> -Pattern $result
            if ($SEL -ne $null) {
                Write-Host "`n $last Contains Matching date "
            } else {
                Write-Host "`n $last Does not Contains date"
            }
        } else {
            Write-Host "`ndate field is blank"
        }
    }
} elseIf ($paths -like "*.txt") {
    if ($paths.Contains("")) {
        $last = $paths.Split("")[-1] #get the last part of the path
        $result = "03-22-2019" #get this date from some where else
        if ($result) {
            #check if pattern string exists in that file.
            $SEL = Select-String -Path <path location> -Pattern $result
            if ($SEL -ne $null) {
                Write-Host "`n $last Contains Matching date "
            } else {
                Write-Host "`n $last Does not Contains date"
            }
        } else {
            Write-Host "`ndate field is blank"
        }
    } else {
        $result = "03-22-2019" #get this date from some where else
        if ($result) {
            #check if pattern string exists in that file.
            $SEL = Select-String -Path <path location> -Pattern $result
            if ($SEL -ne $null) {
                Write-Host "`n $last Contains Matching date "
            } else {
                Write-Host "`n $last Does not Contains date"
            }
        } else {
            Write-Host "`ndate field is blank"
        }
    }
} else {
    Write-Host "other file types"
}
  

Комментарии:

1. Если вы получаете путь через Get-Item / Get-ChildItem, вам следует напрямую проверить свойства Name/BaseName/Extension и, вероятно, использовать switch вместо этой группы if/elseif/else

Ответ №1:

Я бы сделал это немного проще, ниже приведен пример, позволяющий определить, содержит ли файл дату:

 $paths = @("c:path1","c:path2subdir")
ForEach ($path in $paths) {
    $files = Get-ChildItem -LiteralPath $path -file -include "*.sql","*.txt"
    $last = ($path -split "\")[-1] # contains the last part of the path
    $output = ForEach ($file in $files) {
        If (Select-String -path $file -pattern "03-22-2019") {
        "$($file.fullname) contains the date."
        }
        else {
        "$($file.fullname) does not contain the date."
        }
    }
}

$output # outputs whether or not a file has the date string
  

Внешний ForEach цикл перебирает пути в $paths . Внутри этого цикла вы можете делать то, что вам нужно для каждого пути $path . Я использовал $last для сохранения последней части пути в текущей итерации. Вы не сказали, что с этим делать.

Внутренняя система ForEach проверяет каждый файл .txt и .sql на наличие текста даты 03-22-2019. $output сохраняет строку, указывающую, содержит ли каждый файл .txt и .sql строку даты.

Если ваши пути содержат имена файлов, то вы можете использовать следующие альтернативы для получения имени файла (последняя часть пути):

 $path | split-path -leaf # inside of the outer ForEach loop
# Or
$file.name # inside of the inner ForEach loop
  

Комментарии:

1. $($file. полное имя) это то же самое, что $file.name ? если они разные, в чем разница

2. $file.fullname отображает полный путь к имени файла, например R:FolderFile.csv . $file.name показывает только имя файла, например File.csv .

Ответ №2:

Похоже, вам следует начать с foreach после вашей переменной $ paths следующим образом:

 foreach ($path in $paths) {
    if ($path -like "*.sql") {    #Note the use of one single item in the $paths array you have
        $last = $path.split("")[-1]
        $result = #Whatever method you want to use to return a DateTime object
        if ($result) { #### Now, this line doesn't make any sense. Do you want to compare a date to an older date or something? Maybe something like "if ($result -ge (Get-Date).addDays(-1) )
        { # Do your stuff }
  

Выполнение чего-то вроде:

 if ($paths -like "*.sql")
  

Не работает, потому что $paths — это массив, и вы производите сравнение строк, и они никогда не должны встречаться. Теперь, если вы пытаетесь определить, находится ли строка внутри файла, вам следует использовать что-то вроде «Get-Content» или «Import-Csv».

Вы можете использовать командлет «Get-Date», чтобы получить множество различных форматов для даты. Читайте об этом здесь. Если вы пытаетесь сравнить несколько дат с несколькими файлами, я бы начал с цикла for для файлов, как я сделал выше, а затем с цикла for для каждого файла для массива дат. Может быть, что-то вроде этого:

 foreach ($path in $paths) {
    foreach ($date in $dates) { 
        # Get the contents of a file and store it in a variable
        # Search for the string in that variable and store the results in a variable
        # Write to the console
    } # End foreach ($date in $dates)
} # End foreach ($path in $paths)
  

Опубликуйте еще немного обновленного кода, и давайте посмотрим, что у вас получится.