Как я могу использовать командный файл для поиска строки в текстовом файле и заменять всю строку, сохраняя пустые строки [duplicate]

Я придумал следующее решение этой проблемы:

def iter_var1(d):
    for _, row in d.iterrows():
        for v in row["var1"].split(","):
            yield (v, row["var2"])

new_a = DataFrame.from_records([i for i in iter_var1(a)],
        columns=["var1", "var2"])
9
задан djangofan 11 January 2012 в 01:17
поделиться

5 ответов

Это спроектированное поведение FOR / F - он никогда не возвращает пустые строки. Работа заключается в том, чтобы использовать FIND или FINDSTR для префикса строки с номером строки. Если вы не можете гарантировать, что строки не начинаются с разделителя номера строки, тогда вы просто устанавливаете соответствующий разделитель и сохраняете токены 1 *, но используете только второй токен.

::preserve blank lines using FIND, assume no line starts with ]
::long lines are truncated
for /f "tokens=1* delims=]" %%A in ('type "file.txt" ^| find /n /v ""') do echo %%B

::preserve blank lines using FINDSTR, assume no line starts with :
::long lines > 8191 bytes are lost
for /f "tokens=1* delims=:" %%A in ('type "file.txt" ^| findstr /n "^"') do echo %%B

::FINDSTR variant that preserves long lines
type "file.txt" > "file.txt.tmp"
for /f "tokens=1* delims=:" %%A in ('findstr /n "^" "file.txt.tmp"') do echo %%B
del "file.txt.tmp"

Я предпочитаю FINDSTR - он более надежный , Например, FIND может обрезать длинные строки - FINDSTR не до тех пор, пока он читает непосредственно из файла. FINDSTR действительно отбрасывает длинные строки при чтении из stdin через канал или перенаправление.

Если файл может содержать строки, начинающиеся с разделителя, тогда вам нужно сохранить всю строку с префиксом номера строки, а затем использовать поиска и замены, чтобы удалить префикс строки. Вероятно, вы хотите отсрочить расширение при переносе %% A в переменную среды, иначе любой! будет поврежден. Но позже в цикле вам нужно отложить расширение, чтобы выполнить поиск и заменить.

::preserve blank lines using FIND, even if a line may start with ]
::long lines are truncated
for /f "delims=" %%A in ('type "file.txt" ^| find /n /v ""') do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  set "ln=!ln:*]=!"
  echo(!ln!
  endlocal
)

::preserve blank lines using FINDSTR, even if a line may start with :
::long lines >8191 bytes are truncated
for /f "delims=*" %%A in ('type "file.txt" ^| findstr /n "^"') do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  set "ln=!ln:*:=!"
  echo(!ln!
  endlocal
)

::FINDSTR variant that preserves long lines
type "file.txt" >"file.txt.tmp"
for /f "delims=*" %%A in ('findstr /n "^" "file.txt.tmp"') do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  set "ln=!ln:*:=!"
  echo(!ln!
  endlocal
)
del "file.txt.tmp"

Если вам не нужно беспокоиться о преобразовании файла в ASCII, тогда более эффективно отбрасывать канал и пусть FIND или FINDSTR откроют файл, указанный в качестве аргумента, или путем перенаправления.

Существует еще одна работа, которая полностью обходит FOR / F во время процесса чтения. Это выглядит странно, но это более эффективно. Нет ограничений с использованием замедленного расширения, но, к сожалению, у него есть и другие ограничения.

1) строки должны быть завершены символом & lt; CR> & lt; LF> (это не будет проблемой, если вы используете ТИП преобразование файлов)

2) строки должны быть & lt; = 1021 байта (без учета & lt; CR> & lt; LF>)

3) любые конечные управляющие символы удаляются из каждого line.

4) он должен прочитать из файла - вы не можете использовать канал. Поэтому в вашем случае вам понадобится временный файл для преобразования ASCII.

setlocal enableDelayedExpansion
type "file.txt">"file.txt.tmp"
for /f %%N in ('find /c /v "" ^<"file.txt.tmp"') do set cnt=%%N
<"file.txt.tmp" (
  for /l %%N in (1 1 %cnt%) do(
    set "ln="
    set /p "ln="
    echo(!ln!
  )
)
del "file.txt.tmp"
18
ответ дан dbenham 3 September 2018 в 17:55
поделиться

Я написал очень простую программу, которая может служить заменой для команд FIND и FINDSTR, когда они используются для этой цели. Моя программа называется PIPE.COM, и она просто вставляет пустое пространство в пустые строки, поэтому все строки могут быть непосредственно обработаны командой FOR без дальнейших настроек (пока вставленное пространство не заботится). Вот он:

@ECHO off
if not exist pipe.com call :DefinePipe
FOR /F "USEBACKQ delims=" %%A IN (`pipe ^< "build.properties"`) DO (
  ECHO(--%%A--
)
pause
goto :EOF

:DefinePipe
setlocal DisableDelayedExpansion
set pipe=´)€ì!Í!ŠÐŠà€Ä!€ü.t2€ü+u!:æu8²A€ê!´#€ì!Í!².€ê!´#€ì!Í!²+€ê!´#€ì!Í!Šò€Æ!´,€ì!Í!"Àu°´LÍ!ëÒ
setlocal EnableDelayedExpansion
echo !pipe!>pipe.com
exit /B

EDIT: Добавление в качестве ответа на новый комментарий

Код в подпрограмме DefinePipe создает 88-байтную программу под названием pipe. com, которые в основном выполняют процесс, эквивалентный этому псевдо-пакетному коду:

set "space= "
set line=
:nextChar
   rem Read just ONE character
   set /PC char=
   if %char% neq %NewLine% (
      rem Join new char to current line
      set line=%line%%char%
   ) else (
      rem End of line detected
      if defined line (
         rem Show current line
         echo %line%
         set line=
      ) else (
         rem Empty line: change it by one space
         echo %space%
      )
   )
goto nextChar

Таким образом, пустые строки во входном файле изменяются линиями с одним пробелом, поэтому команда FOR / F не пропускает больше Oни. Это работает «до тех пор, пока вставленное пространство не заботится», как я сказал в своем ответе.

Обратите внимание, что программа pipe.com не работает в 64-битных версиях Windows.

Антонио

2
ответ дан Aacini 3 September 2018 в 17:55
поделиться

Как упоминалось в , этот отвечает на вышеупомянутый вопрос, кажется, что строки не пропускаются по умолчанию, используя for /f в (по крайней мере) Windows XP (Сообщество - обновите этот ответ путем тестирования приведенных ниже командных команд в вашем пакете обновления и пакета обновления Windows). & nbsp; & nbsp; & nbsp; & nbsp; EDIT: комментарий Jeb ниже , кажется, что команда ping, по меньшей мере, Windows XP, является & nbsp; & nbsp; & nbsp; заставляя for /f создавать <CR> 'вместо пустых строк (если кто-то знает, почему именно, would & nbsp; & nbsp; & nbsp; оцените это, если они могут обновить этот ответ или комментарий).

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; В качестве обходного пути кажется, что второй маркер с разделителем по умолчанию (<space> / %%b в этом примере) & nbsp; & nbsp; & nbsp; возвращает в качестве blank, который работал для моей ситуации устранения пустые строки посредством «родительского» & nbsp; & nbsp; if обусловлены вторым токеном в начале for /f, например:

   for /f "tokens=1,2*" %%a in ('ping -n 1 google.com') do (
      if not "x%%b"=="x" (
         {do things with non-blank lines}
      )
   )

Используя следующий код:

@echo off
systeminfo | findstr /b /c:"OS Name" /c:"OS Version" 
echo.&echo.
ping -n 1 google.com
echo.&echo.
for /f %%a in ('ping -n 1 google.com') do ( echo "%%a" )
echo.&echo.&echo --------------&echo.&echo.
find /?
echo.&echo.
for /f %%a in ('find /?') do ( echo "%%a" )
echo.&echo.
pause

.... следующее, что я вижу в Windows XP, Windows 7 и Windows 2008, будучи единственными тремя версиями и amp; сервисные пакеты Windows У меня есть готовый доступ к:

Windows XP Pro SP3 [/g3]

Windows 7 Enterprise SP1 [/g4]

Windows Server 2008 R2 Enterprise SP1 [/g5]

0
ответ дан Community 3 September 2018 в 17:55
поделиться

Благодаря dbenham это работает, хотя и немного отличается от его предложения:

::preserve blank lines using FIND, no limitations
for /f "USEBACKQ delims=" %%A in (`type "file.properties" ^| find /V /N ""`) do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  set "ln=!ln:*]=!"
  echo(!ln!
  endlocal
)
0
ответ дан djangofan 3 September 2018 в 17:55
поделиться

Выходные строки, включая пустые строки

Вот метод, который я разработал для моего собственного использования.

Сохраните код в виде пакетного файла, скажем, SHOWALL.BAT и передать исходный файл в качестве параметра командной строки.

Выход может быть перенаправлен или передан по каналам.

@echo off

for /f "tokens=1,* delims=]" %%a in ('find /n /v "" ^< "%~1"') do echo.%%ba

exit /b

ПРИМЕРЫ:

showall source.txt

showall source.txt > destination.txt

showall source.txt | FIND "string"

Нечетность - это включение '^ & lt;' (перенаправление), а не только следующее:

for /f "tokens=1,* delims=]" %%a in ('find /n /v "" "%~1"') do echo.%%ba

Путем пропуска перенаправления выводится ведущая пустая строка.

1
ответ дан Paul Tomasi 3 September 2018 в 17:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: