Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Построчное чтение файла и работа с элементами строки (http://forum.oszone.net/showthread.php?t=346615)

Jackoe89 05-10-2020 11:43 2935575

Построчное чтение файла и работа с элементами строки
 
Здравствуйте! Никак не получается разобраться: Нужно прочитать текстовый файл, и в каждой строке попарно заменить слова между собой (1-е со 2-м, 3-е с 4-м и т.д)

Elven 05-10-2020 14:38 2935589

было бы неплохо увидеть пример строки, а еще лучше пример файла.
Ну и так, немного на вентилятор:
чем разделяются "слова";
что делать если количество слов в строке нечетное;
какая кодировка у файла;
чем строки заканчиваются;
куда, наконец, резльтат записывать?

Iska 05-10-2020 17:24 2935607

По рабоче-крестьянски:
Скрытый текст
Код:

Get-Content -Path 'C:\Мои проекты\0322\0001.txt' |`
    ForEach-Object -Process {
        $aWords = $_.Split()
        $iCount = $aWords.Count - $aWords.Count % 2

        for($i = 0; $i -lt $iCount; $i = $i + 2) {
            $sWord          = $aWords[$i]
            $aWords[$i]    = $aWords[$i + 1]
            $aWords[$i + 1] = $sWord
        }

        $aWords -join ' '
    }



Полагаю, можно быстрее сделать замену регуляркой.

Foreigner 05-10-2020 18:23 2935612

Код:

$text = 'один два три четыре пять'
$arr = $text.Split()

$n = [Collections.ArrayList] @()

for ($i = 0; $i -lt $arr.Count; $i++)
{
    switch ( $i % 2 )
    {
        1  { $n.Insert(($i-1),$arr[$i]) }
        0  { $n.Insert($i,$arr[$i]) }
    }
}

$n -join ' '


greg zakharov 05-10-2020 21:15 2935630

Длина строк (количество слов в строке), как и пунктуация, действительно автором темы не были оговорены. А так можно подбросить решение в "функциональном" стиле.
Код:

$text = @'
два один четыре три пять
это а длинная просто строка тестовая
'@

$text | ConvertFrom-Csv -Delimiter ' ' -Header (($arr =
  1..($text.Split("`n") | Sort-Object Length -Bottom 1 | Measure-Object -Word).Words
)) | Select-Object -Property ([String[]]$arr.ForEach{$_ + ($_ % 2 -eq 0 ? -1 : 1)}) |
ConvertTo-Csv -Delimiter ' ' -UseQuotes 0 | Select-Object -Skip 1

Что касается скорости и текстовых файлов (больших в частности), лучше воспользоваться SQLite.

greg zakharov 10-10-2020 22:39 2936056

Одно из возможных решений при наличии пунктуации в тексте - токенизация на манер того, как это реализовано в PSParser.
Код:

@'
каждый И в, вечер назначенный час,
(это Иль снится только мне?)
стан Девичий, схваченный шелками,
туманном В окне движется.

медленно И, меж пройдя пьяными,
без Всегда одна, спутников,
духами Дыша туманами и,
садится Она окна у.
'@.Split("`n").ForEach{
  $i, $str = 0, $_

  $arr = ($str -split '(\p{L}+|\p{P})(?:\s+)?').Where{$_}.ForEach{
    [PSCustomObject]@{
      Type = $_ -match '\p{P}' ? 'Punctuation' : 'Word'
      Index = ++$i
      Value = $_
    }
  }

  $w  = $arr.Where{$_.Type -eq 'Word'}
  $sz = $w.Count % 2 -eq 0 ? $w.Count : $w.Count - 1

  for ($i = 0; $i -lt $sz; $i += 2) {
    $w[$i].Index, $w[$i + 1].Index = $w[$i + 1].Index, $w[$i].Index
  }

  ($w + $arr.Where{$_.Type -eq 'Punctuation'} |
  Sort-Object Index).Value -join ' ' -replace '\s(\p{P})', '$1'
}

При работе с потоками производительность повысится, но не сравнится по скорости с использованием указателей (правда для этого нужно знать опкоды IL, а объяснять каждый из них не хочется, поэтому примера не последует).


Время: 20:40.

Время: 20:40.
© OSzone.net 2001-