Показать полную графическую версию : findstr при записи в тот же файл
Мне нужно удалить заданную строку в текстовом файле. Конкретно нужно удалить ай пи и перезаписать файл без данной строки.
Судя по ману команды findstr делается это так:
findstr /I /V "192.168.1.101" test.txt
Результат будет вывод файла без искомой строки.
Однако, при добавлении кода с записью в тот же самый файл, текст в файле затирается полностью.
Батник:
findstr /I /V "192.168.1.101" test.txt>test.txt
echo Press any key...
pause > nul
Результат: пустой файл test.txt. Что не так делаю?
PS А при чем тут единичка?
Как-то давным давно я уже сталкивался с этой проблемой на семёрке, убил в тот раз целый день и пришлось всё делать через зад. А щас то же самое на ДЕСЯТКЕ!!!
Кто-нибудь мне скажет что тут происходит???
findstr /I /V "192.168.1.101" test.txt>test.txt
echo Press any key...
pause > nul
С кодом всё понятно вроде. Здесь командой findstr хочу убрать строку с айпи из файла.
Теперь выполняем батник.
C:\debug\cmdtest>findstr /I /V "192.168.1.101" test.txt 1>test.txt
C:\debug\cmdtest>echo Press any key...
Press any key...
C:\debug\cmdtest>pause 1>nul
Главный вопрос: ОТКУДА ЭТА ЕДИНИЧКА???
В результате он мне затирает текст! Или я отстал от жизни или это фича???
С кодом всё понятно вроде. Здесь командой findstr хочу убрать строку с айпи из файла. »
Главный вопрос: ОТКУДА ЭТА ЕДИНИЧКА???
В результате он мне затирает текст! Или я отстал от жизни или это фича??? »
Главный ответ:
единичка - это числовой эквивалент дескриптора вывода в консоль, который перенаправлен в nul.
Но с кодом, всё же, Вы недопонимаете...
>test_out.txt findstr /ivc:"192.168.1.101" test.txt
при необходимости, файл с выходными данными переименовать
Привет!
У меня было мнение, что причина в единичке, якобы команда определяет лишний символ в параметрах. Но похоже что проблема глубже...
Ну так и что? Тема сводится к обсуждению как убрать строку с айпи? Твой код тоже не работает. Точнее он работает при вводе команды без перенаправления в левый файл, как работает и у меня. А вот в тот же файл почему-то облом.
Пора тему переименовать в разборки с командой findstr...
С кодом всё понятно вроде. »
Совсем непонятно.
1. Когда Вы используйте в таком виде вывод в файл в той же команде, которой пытаетесь читать из него — происходит следующее:
https://i.imgur.com/McWRbgW.png
В итоге — как видите, Ваша команда радостно пытается читать из уже пустого файла. Вы обратили внимание, что у коллеги YuS_2 идёт чтение из одного файла, а вывод делается в другой?
2. Единичка в:
C:\debug\cmdtest>findstr /I /V "192.168.1.101" test.txt 1>test.txt »
— это, как уже написал выше коллега YuS_2, просто номер дескриптора стандартного потока вывода, stdout (Стандартные потоки — Википедия (https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B0%D0%BD%D0%B4%D0%B0%D1%80%D1%82%D0%BD%D1%8B%D0%B5_%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0 %B8)). Её показывает интерпретатор команд при включённом режиме отображения команд (попросту — когда Вы не использовали echo off). На опустошение файла перед его чтением она никоим образом не влияет и влиять не может.
который перенаправлен в nul. »
А вот это не понял. Где там nul?!
Твой код тоже не работает. »
Работает.
Точнее он работает при вводе команды без перенаправления в левый файл, как работает и у меня. А вот в тот же файл почему-то облом.
Пора тему переименовать в разборки с командой findstr... »
Объяснение — на скриншоте: в указанном Вами виде файл test.txt сначала обнуляется, и лишь затем идёт попытка чтения из него. findstr.exe тут совершенно не при чём, вместо неё может быть любой исполняемый файл.
Ну затирает он вначале и что? Из скриншота я не понял, и хде там решение проблемы?!
echo 123>test.txt
почему не затирается?
точно я отстал от жизни, пора вешаться...
А вот это не понял. Где там nul?! »
здесь:
C:\debug\cmdtest>pause 1>nul »
====================================================
решение проблемы?! »
Какой проблемы? Проблем никаких нет, я ведь Вам написал:
при необходимости, файл с выходными данными переименовать »
в тот же test.txt с перезаписью...
Ну и переименуй... Или я один туплю?
c:\debug\cmdtest>type test.txt
abc
192.168.1.101
c:\debug\cmdtest>>test.txt findstr /ivc:"192.168.1.101" test.txt
c:\debug\cmdtest>type test.txt
c:\debug\cmdtest>
Ну затирает он вначале и что? »
В общем, в cmd нельзя в одном наборе команд и читать из файла и записывать в него...
Ну и переименуй »
от переименуя и слышу... :)
В смысле, тебе надо, ты и переименовывай... где тебя манерам учили?
В смысле, тебе надо, ты и переименовывай...
Еще раз: изначально переименовал.
При чем тут манеры? в итоге я прав
Ну есть же решение, только без записи в левый файл. Как это сделать ума не приложу...
Ну есть же решение, только без записи в левый файл. »
чем не устраивает решение:
<test.txt>+ findstr /ivc:"192.168.1.101"&move+ test.txt
?
Религиозные принципы мешают? :)
Зачем? Я и так мог бы наплодить кучу го%нокода и не подымать тему. Дело принципа. И всё можно, вот решение:
for /f "usebackq" %%a in (`findstr /V "192.168.1.101" test.txt`) do (set content=%%a)
echo %content%>test.txt
Всё пашет, тему можно закрыть
Зачем? Я и так мог бы наплодить кучу го%нокода и не подымать тему. »
Если тебе нужна была помощь, то тебе её дали, но именно твой, как ты выразился, го%нокод, точно никому не нужен...
1. Добавь в свой файл несколько строк и увидишь, почему го%нокод (его можно исправить, кстати)
2. Добавь в свой файл тысяч сто строк и замеряй скорость обработки (даже в случае с исправленным вариантом)
3. Посыпать голову пеплом не требуется, но манеры свои, всё же, подправь... на будущее.
Ну затирает он вначале и что? »
И ничего. В том-то и дело, что НИ-ЧЕ-ГО. Файл становится пустой. И Ваша findstr.exe получает на вход этот самый совершенно пустой файл test.txt.
echo 123>test.txt
почему не затирается? »
Файл как раз таки усекается до нулевого размера. А затем уже в него пишется «123».
Из скриншота я не понял, и хде там решение проблемы?! »
На скриншоте не решение проблемы, а объяснение её появления — а) почему так, и б) почему именно так, а не иначе.
Решение же банально — разнести чтение из и вывод в один и тот же файл, не делать этого одновременно в пределах одной команды.
Или я один туплю? »
К сожалению, да. Видно, что Вы не понимаете, как происходит усечение исходного файла test.txt. Ну, давайте попробуем ещё раз:
findstr /I /V "192.168.1.101" test.txt>test.txt »
Выделенное начинает выполняться в первую очередь. Что при этом происходит — файл test.txt открывается, и его размер усекается до нуля. В него ещё ничего не выведено, он просто подготовлен для записи. Затем начинает выполняться findstr.exe, читает переданный ей аргумент, открывает этот самый файл test.txt — а там уже пусто. Понимаете? Команде findstr.exe попросту уже нечего фильтровать, файл test.txt пустой, поскольку Вы указали перенаправить в него вывод из той же самой команды.
в итоге я прав »
Нет.
Ну есть же решение, только без записи в левый файл. Как это сделать ума не приложу... »
Призовите коллег megaloman и alpap, они делали подобное через группировку команд и фильтры с more.
здесь: »
Аааа! Я только предыдущую единичку увидел, в:
C:\debug\cmdtest>findstr /I /V "192.168.1.101" test.txt 1>test.txt »
а вторую — нет. Спасибо, ясно, разобрался, доглядел ;).
И всё можно, вот решение:
for /f "usebackq" %%a in (`findstr /V "192.168.1.101" test.txt`) do (set content=%%a)
echo %content%>test.txt
Всё пашет, тему можно закрыть »
Вы издеваетесь? Данный код а) потеряет все пустые строки в файле test.txt, но это не так страшно, как б) сохранит из всего содержимого файла test.txt только его последнюю строку:
@echo off
setlocal enableextensions enabledelayedexpansion
echo --- До... --------------------------
type "test.txt"
echo ------------------------------------
rem Здесь начало Вашего кода
for /f "usebackq" %%a in (`findstr /V "192.168.1.101" test.txt`) do (set content=%%a)
echo %content%>test.txt
rem Здесь окончание Вашего кода
echo --- ...и после ---------------------
type "test.txt"
echo ------------------------------------
endlocal
exit /b 0
https://i.imgur.com/fEH4IE6.png
Призовите коллег megaloman и alpap, они делали подобное через группировку команд и фильтры с more. »
Зачем?
тут главное непонятно: зачем именно такое действие, что за религия запрещает применение промежуточного файла?
... в любом случае, представленный выше вариант (http://forum.oszone.net/post-2828215.html#post2828215), это наиболее быстрый вариант.
Можно, конечно, через цикл for такое осуществить (как попытался сделать ТС, пусть и коряво...), т.к. команды, результат которых разбирается в цикле, выполняются в новом процессе, но это очень медленно и неэффективно в итоге, плюс ещё со своими особенностями (такими как съедание пустых строк и т.п.)
Зачем? »
Ну, как — зачем?! Из прынципа! :) Вы же сами об этом чуть выше пишете.
Вы же сами об этом чуть выше пишете. »
не-не-не, про прынципы, не мое перо начеркало :)
не-не-не, про прынципы, не мое перо начеркало »
«У меня все ходы записаны»™ ;):
Религиозные принципы мешают? »
У меня все ходы записаны »
А, ну так то вопрос же был, не утверждение... :)
Всё! Товарищ один помог, все недостатки for исправляются параметрами, но всё равно корявенько получилось эт да! Батники в винде, когда дело касается обработки текста - это конечно же ещё та мозголомка башка кипит.
setlocal enableDelayedExpansion
set NL=^
set content=
for /f "usebackq delims=: tokens=1* eol=" %%a in (`findstr /V /N "192.168.1.101" test.txt`) do set content=!content!%%b!NL!
echo !content!
все недостатки for исправляются параметрами, »
Не все.
но всё равно корявенько получилось эт да! »
Вы даже не представляете — насколько:
@echo off
setlocal enableextensions enabledelayedexpansion
set NL=^
set content=
for /f "usebackq delims=: tokens=1* eol=" %%a in (`findstr /V /N "192.168.1.101" test.txt`) do set content=!content!%%b!NL!
>"Result.txt" echo !content!
endlocal
exit /b 0
https://i.imgur.com/BvjDNYV.png
— добро пожаловать в смешанный мир Windows+Unix! CrLf и Lf в одном флаконе!
Как поведёт себя приложение, которое должно будет работать с получившимся кадавром — вопрос.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.