Пакетный скрипт для удаления возврата каретки в несколько строк текста, кроме каждой пятой - PullRequest
2 голосов
/ 29 марта 2011

У меня есть текстовый файл, содержащий:

http://website1.com
http://website2.com
http://website3.com
http://website4.com
http://website5.com
http://website6.com
http://website7.com
http://website8.com
http://website9.com
http://website10.com
http://website11.com
http://website12.com
http://website13.com
http://website14.com
http://website15.com

Я хочу сгруппировать текст по пяти «веб-сайтам», удалив все возвраты каретки / переводы строк за исключением 5-го, 10-го, 15-го и т. Д. Одного.Вывод должен выглядеть примерно так:

http://website1.comhttp://website2.comhttp://website3.comhttp://website4.comhttp://website5.com
http://website6.comhttp://website7.comhttp://website8.comhttp://website9.comhttp://website10.com
http://website11.comhttp://website12.comhttp://website13.comhttp://website14.comhttp://website15.com

Что мне сделать, чтобы добиться этого?

Ответы [ 3 ]

1 голос
/ 29 марта 2011

Предполагая, что вам нужен пакетный файл, это довольно просто:

@echo off
rem We need delayed expansion inside the loop
setlocal enableextensions enabledelayedexpansion
rem Initialize the variables we are going to use to avoid using stale environment vars
set LIST=
set COUNT=0
rem Iterate over the lines in the text file
for /f "delims=" %%l in (list.txt) do (
  rem Append the current line to the list
  set LIST=!LIST!%%l
  rem Count how many we got
  set /a COUNT+=1
  rem If we have five items already
  set /a "COUNT%%=5"
  if !COUNT!==0 (
    rem Output them and reset the list
    echo !LIST!
    set LIST=
  )
)
rem Output the remainder if the list does not contain k×5 lines
if defined LIST echo %LIST%

Перенаправить вывод этого пакета в другой файл и, если необходимо, скопировать поверх старого (никогда не перенаправлять на входной файл :-)).

Вариант, который напрямую записывает новый выходной файл (list_new.txt):

@echo off
setlocal enableextensions enabledelayedexpansion
set LIST=
set COUNT=0
del list_new.txt
for /f "delims=" %%l in (list.txt) do (
  set LIST=!LIST!%%l
  set /a COUNT+=1
  set /a "COUNT%%=5"
  if !COUNT!==0 (
    >>list_new.txt echo !LIST!
    set LIST=
  )
)
if defined LIST >>list_new.txt echo %LIST%
0 голосов
/ 29 марта 2011

Основано на решении Джои, это только для безопасной обработки всех специальных символов %&|<>", а также !^.

Это только необходимо, если вы ожидаете ! в данных вашего файла.
В любом другом случае код Джои лучше и легче для чтения.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Initialize the variables we are going to use to avoid using stale environment vars
set LIST=
set COUNT=0
rem Iterate over the lines in the text file
rem We need toggling the delayed expansion inside the loop
rem always disabled if using %%l, enabled for using the variables
for /f "delims=" %%l in (list.txt) do (
  rem Append the current line to the list, %%l is only safe if delayed expansion is disabled
  set "line=%%l"
  setlocal EnableDelayedExpansion
  rem To use the line variable, delayed expansion has to be enabled
  for %%a in ("!LIST!!line!") do (
    endlocal
    set "LIST=%%~a"
  )

  set /a COUNT+=1
  rem Count how many we got
  rem If we have five items already
  setlocal EnableDelayedExpansion
  if !COUNT! GEQ 5 (
    rem Output them and reset the list
    echo(!LIST!
    endlocal
    set "LIST="
    set COUNT=0
  ) ELSE ( 
    endlocal 
  )
)
setlocal EnableDelayedExpansion
rem Output the remainder if the list does not contain k×5 lines
if defined LIST echo(!LIST!

Почему это так сложно?

Проблема в том, что %% a (переменные FOR-Loop-Variables) раскрываются непосредственно перед выполнением отложенного расширения. У вас возникают проблемы, если содержимое %% a содержит !, а затем вы теряете также ^ (только если существует один или несколько !).
Но вам нужно отложенное расширение, чтобы показать или сравнить содержимое переменных внутри цикла for (забудьте о вызове %% var %%).
Расширение с задержанным синтаксисом! Переменная! всегда безопасен, не зависит от содержимого, так как это последний этап синтаксического анализатора.

Но, к сожалению, включение / отключение отложенного опыта. всегда создает новый контекст переменной, при выходе из этого контекста вы теряете все изменения переменных.
Поэтому я использую внутренний цикл FOR-Loop для перехода от enabledDelayed-Context обратно к disabledDelayed-Context, поэтому LIST-var содержит правильные данные.

надеюсь, кто-то понимает, что я пытаюсь объяснить.
Еще несколько объяснений о фазах можно найти в как сценарии синтаксического анализа cmd.exe

0 голосов
/ 29 марта 2011

Если у вас есть выбор, вот вам Ruby один вкладыш

C:\work> ruby -ne 'print $.%5==0? $_ :$_.chomp' file
http://website1.comhttp://website2.comhttp://website3.comhttp://website4.comhttp://website5.com
http://website6.comhttp://website7.comhttp://website8.comhttp://website9.comhttp://website10.com
http://website11.comhttp://website12.comhttp://website13.comhttp://website14.comhttp://website15.com
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...