none
А возможно ли с помощью Poweshell получить содержимое между первым и последним тегами?

    Вопрос

  • Есть текстовый файл в котором нужно получить содержимое между тегом открытия { и тегом закрытия } и полученные данные записать в новый файл одной строкой.

    То есть на входе:

    file1.txt

    {20181125000044,N,
    {0,0},826,0,3,626891,2,I,"",0,
    {"U"},"",1,20,0,1,0,
    {0}
    },
    {20181125000044,N,
    {0,0},826,0,3,626891,3,I,"",0,
    {"P",
    {6,
    {"S","remote.access@accountingsuite.com"},
    {"S","NT AUTHORITY\IUSR"}
    }
    },"",1,20,0,1,0,
    {0}
    },
    {20181125000044,C,
    {24327876f86c0,135},826,0,3,626891,5,I,"",0,
    {"U"},"",1,20,0,1,0,
    {0}
    },
    {20181125000044,C,
    {24327876f86c0,135},826,0,3,626891,6,I,"",0,
    {"U"},"",1,20,0,1,0,
    {0}
    },


    А на выходе file2.txt

    {20181125000044,N,{0,0},826,0,3,626891,2,I,"",0,{"U"},"",1,20,0,1,0,{0}},
    {20181125000044,N,{0,0},826,0,3,626891,3,I,"",0,{"P",{6,{"S","r.a@domain.com"},{"S","NT AUTHORITY\IUSR"}}},"",1,20,0,1,0,{0}},
    {20181125000044,C,{24327876f86c0,135},826,0,3,626891,5,I,"",0,{"U"},"",1,20,0,1,0,{0}},
    {20181125000044,C,{24327876f86c0,135},826,0,3,626891,6,I,"",0,{"U"},"",1,20,0,1,0,{0}},


    27 ноября 2018 г. 13:22

Ответы

  • (-join (gc file1.txt)) -split "" |% {$i=0;$x=""}{if ($_ -eq '{'){$i++} elseif($_ -eq '}'){$i--};if ($_ -eq "," -and $i -eq 0){$x=$x+$_+"`r`n"}else{$x=$x+$_}}{$x|out-file file2.txt}

    ну наверн и покороче можно было :-)


    • Изменено Svolotch 27 ноября 2018 г. 17:09
    • Предложено в качестве ответа eclegolas 28 ноября 2018 г. 7:23
    • Помечено в качестве ответа Dalniy_Svet 28 ноября 2018 г. 11:17
    27 ноября 2018 г. 17:03
  • gc file1.txt|% -beg {$x=""}-pro {$x=$x+$_;If ($_ -eq "},"){$x|out-file file2.txt -append;$x=""}}

    попробуйте так (без проверки, просто предполагаем что строчка "}," это всегда закрывающий тег)


    • Изменено Svolotch 28 ноября 2018 г. 12:09
    • Помечено в качестве ответа Dalniy_Svet 28 ноября 2018 г. 12:53
    28 ноября 2018 г. 12:08
  • (gc file1.txt -TotalCount 2 -enc ascii),(-join (gc file1.txt -enc ascii|select -skip 2)  -replace "},{20(\d{12})", "},`r`n{20`$1")|out-file file2.txt

    (gc file1.txt -TotalCount 2 -enc ascii) - читаем первые 2 строки

    (gc file1.txt -enc ascii|select -skip 2) - читаем все кроме первых двух

    -join лепит из второй пачки одну большую военную строку

    что делает реплейс я уже писал

    • Изменено Svolotch 28 ноября 2018 г. 13:53
    • Помечено в качестве ответа Dalniy_Svet 28 ноября 2018 г. 14:24
    28 ноября 2018 г. 13:42

Все ответы

  • -join (gc 1.txt) > 2.txt

    27 ноября 2018 г. 13:39
    Отвечающий
  • (-join (gc file1.txt)) -split "" |% {$i=0;$x=""}{if ($_ -eq '{'){$i++} elseif($_ -eq '}'){$i--};if ($_ -eq "," -and $i -eq 0){$x=$x+$_+"`r`n"}else{$x=$x+$_}}{$x|out-file file2.txt}

    ну наверн и покороче можно было :-)


    • Изменено Svolotch 27 ноября 2018 г. 17:09
    • Предложено в качестве ответа eclegolas 28 ноября 2018 г. 7:23
    • Помечено в качестве ответа Dalniy_Svet 28 ноября 2018 г. 11:17
    27 ноября 2018 г. 17:03
  • (-join (gc file1.txt)) -split "" |% {$i=0;$x=""}{if ($_ -eq '{'){$i++} elseif($_ -eq '}'){$i--};if ($_ -eq "," -and $i -eq 0){$x=$x+$_+"`r`n"}else{$x=$x+$_}}{$x|out-file file2.txt}

    ну наверн и покороче можно было :-)

    Спасибо! Это работает, но сожалению только на относительно не больших файлах. На файле объёмом 8 Мб и 441k строк срок ожидания привысил 4  часа.

    28 ноября 2018 г. 11:21
  • естественно, он же посимвольно парсит.

    у вас формат файла всегда такой что "закрывающий" тег "}," всегда на отдельной строчке и никакие другие строчки такие же кроме "закрывающей" не ожидаются?

    ну щас попробую набросать что нить более оптимизированное под мое предположение выше.
    • Изменено Svolotch 28 ноября 2018 г. 11:46
    28 ноября 2018 г. 11:44
  • gc file1.txt|% -beg {$x=""}-pro {$x=$x+$_;If ($_ -eq "},"){$x|out-file file2.txt -append;$x=""}}

    попробуйте так (без проверки, просто предполагаем что строчка "}," это всегда закрывающий тег)


    • Изменено Svolotch 28 ноября 2018 г. 12:09
    • Помечено в качестве ответа Dalniy_Svet 28 ноября 2018 г. 12:53
    28 ноября 2018 г. 12:08
  • (-join (gc 1.txt)) -replace "}},{", "}},`n{" > 2.txt

    или

    (-join (gc 1.txt)) -replace "},{(\d{14})", "},`n{`$1" > 2.txt




    • Изменено KazunEditor 28 ноября 2018 г. 12:18
    • Предложено в качестве ответа Svolotch 28 ноября 2018 г. 12:42
    28 ноября 2018 г. 12:08
    Отвечающий
  • естественно, он же посимвольно парсит.

    у вас формат файла всегда такой что "закрывающий" тег "}," всегда на отдельной строчке и никакие другие строчки такие же кроме "закрывающей" не ожидаются?

    ну щас попробую набросать что нить более оптимизированное под мое предположение выше.

    Спасибо!

    Открывающий строку тег всегда {дата и время в формате YYYYMMDDHHMMSS

    пример: {20181125080949

    Закрывающий строку тег всегда }, 

    пример: },

    Но внутри может быть любое количество {} и , 

    28 ноября 2018 г. 12:13
  • короче чем подробнее шаблон строки пришлете, тем точнее будет вариант.

    в моем первом случае посимвольно считается сумма открывающихся и закрывающихся скобочек, в отстальных, моем и казуна, рассматриваем вариант примерной уникальной комбинации закрывашки\закрывашки+открывашки

    З.Ы. это лог чего хоть, если не секрет?

    • Изменено Svolotch 28 ноября 2018 г. 12:24
    28 ноября 2018 г. 12:23
  • короче чем подробнее шаблон строки пришлете, тем точнее будет вариант.

    в моем первом случае посимвольно считается сумма открывающихся и закрывающихся скобочек, в отстальных, моем и казуна, рассматриваем вариант примерной уникальной комбинации закрывашки\закрывашки+открывашки

    З.Ы. это лог чего хоть, если не секрет?

    Не секрет. Лог инфобаз 1С в формате lgp. Хочу загнать его в сервис Loggly в наиболее удобном для восприятия виде. У логли нет специальных парсеров для 1С.
    28 ноября 2018 г. 12:39
  • Да, все варианты работают очень быстро и результат вроде правильный.

    А можно еще сделать так что бы первые две строки переносились в новый файл без изменений?

    И еще, заметил странную особенность, у всех 3 скриптов создаваемый файл по размеру почти в два раза больше чем исходный, хотя количество символов не увеличивается, а число строк даже меньше.

    28 ноября 2018 г. 12:58
  • второй вариант казуна тоже интересный

    (-join (gc 1.txt)) -replace "},{(\d{14})", "},`n{`$1" > 2.txt

    можно даже так

    (-join (gc 1.txt)) -replace "},{20(\d{12})", "},`r`n{20`$1" |out-file file2.txt -enc ASCII

    сливаем все в одну большую строчку, и расставляем после запятой значки перевода каретки и новой строки везде где встречается комбинация "},{20(и_еще_12_цифр)"  

    размер - потомучто юникод, вместо >2.txt ставьте 

    |out-file file2.txt -enc ASCII
    • Изменено Svolotch 28 ноября 2018 г. 13:14
    28 ноября 2018 г. 13:13
  • (gc file1.txt -TotalCount 2 -enc ascii),(-join (gc file1.txt -enc ascii|select -skip 2)  -replace "},{20(\d{12})", "},`r`n{20`$1")|out-file file2.txt

    (gc file1.txt -TotalCount 2 -enc ascii) - читаем первые 2 строки

    (gc file1.txt -enc ascii|select -skip 2) - читаем все кроме первых двух

    -join лепит из второй пачки одну большую военную строку

    что делает реплейс я уже писал

    • Изменено Svolotch 28 ноября 2018 г. 13:53
    • Помечено в качестве ответа Dalniy_Svet 28 ноября 2018 г. 14:24
    28 ноября 2018 г. 13:42
  • Спасибо, это то что нужно!
    28 ноября 2018 г. 14:25