Имя пользователя:
Пароль:
 | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - findstr при записи в тот же файл

Ответить
Настройки темы
CMD/BAT - findstr при записи в тот же файл

Новый участник


Сообщения: 44
Благодарности: 6

Профиль | Отправить PM | Цитировать


Изменения
Автор: TolikD
Дата: 23-08-2018
Описание: покурил перенаправление вывода
Мне нужно удалить заданную строку в текстовом файле. Конкретно нужно удалить ай пи и перезаписать файл без данной строки.
Судя по ману команды 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
Главный вопрос: ОТКУДА ЭТА ЕДИНИЧКА???
В результате он мне затирает текст! Или я отстал от жизни или это фича???

Отправлено: 18:55, 23-08-2018

 

Аватара для YuS_2

Crazy


Contributor


Сообщения: 1235
Благодарности: 517

Профиль | Отправить PM | Цитировать


Цитата TolikD:
Всё! Товарищ один помог, все недостатки for исправляются параметрами »
Зачем?
Зачем демонстрировать свою, как бы это сказать помягче... неосведомленность, в форме утверждений?
Задавай лучше вопросы, найдутся люди - подскажут обязательно... может быть не сразу, но подскажут.

Во-первых:
Цитата:
The maximum individual environment variable size is 8192bytes
расшифровать, что это означает?
Вот тебе рабочий вариант:
Код: Выделить весь код
for /f "delims=" %%a in ('findstr /ivc:"192.168.1.101" test.txt^&del test.txt') do >>test.txt echo %%a
с пустыми строками разбирайся сам...

Во-вторых:
выше уже подсказали возможные траблы.

В-третьих:
Как я уже говорил, скорость обработки, также никуда не денется...
Тот вариант с промежуточным файлом, который предложен выше, обрабатывает файл в ~100000 строк (~1,2Mb) за:
Код: Выделить весь код
Start: 24.08.2018  9:20:41,81
Stop: 24.08.2018  9:20:42,17
причем все символы и пустые строки сохраняются...

В общем, всё остальное (на cmd, естественно), при такой постановке задачи - от лукавого... даже если возникнет иллюзия нормальной работы. ;-)

-------
scio me nihil scire. Ѫ


Последний раз редактировалось YuS_2, 24-08-2018 в 06:33.

Это сообщение посчитали полезным следующие участники:

Отправлено: 06:26, 24-08-2018 | #21



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Ветеран


Contributor


Сообщения: 2735
Благодарности: 1699

Профиль | Отправить PM | Цитировать


Не по теме: без findstr cmd+js без некошерного создания второго файла, пустые строки сохраняются, всякие непристойные символы сохраняются и не мешают. По сравнению с голым cmd длинный код
Удаляем строку, содержащую указанную подстроку
Не грубите писателю, он пишет как умеет
Код: Выделить весь код
@set @E=1; /*
@Echo Off
cls
       	Set "FileIn=Z:\Box_In\Улицы разбитых фонарей 22.txt"
	Set "DelFind=192.168.1.101"
	
	Cscript //NoLogo /E:jscript "%~dpnx0" "%FileIn%" "%DelFind%"  
pause
GoTo :Eof

*/
var oArg = WScript.Arguments;
var nArg = oArg.Count();

if (nArg < 2) {
	WScript.Echo("Error! Invalid number of arguments!");
	WScript.Quit(240);
}
var FText=oArg(0);

var FSO=WScript.CreateObject("Scripting.FileSystemObject");

var InFile;
try {InFile = FSO.OpenTextFile(FText,1);}
catch (e) {
   if (e !=0 ) {
	WScript.Echo("Error! " + FText + "  " + e.description);
       	WScript.Quit(1);
     }
}
var TextAll = InFile.ReadAll();
InFile.Close();

var i0 = TextAll.indexOf(oArg(1));
if (i0 < 0) {
	WScript.Echo("Error! String not found! \n" + oArg(1));
	WScript.Quit(2);
}

var C10=String.fromCharCode(10);
var i1 = TextAll.lastIndexOf(C10,i0);
var i2 = TextAll.indexOf(C10,i0);

if (i1 < 0 && i2 < 0) {
	TextAll="";
}
else
{
	if (i2 < 0) {TextAll=TextAll.substring(0,i1+1)};
	if (i1 <= 0) {TextAll = TextAll.substring(i2+1,TextAll.length)};
	if (i1 >0 && i2 >= 0) {TextAll=TextAll.substring(0,i1+1) + TextAll.substring(i2+1,TextAll.length)};
}

InFile = FSO.OpenTextFile(FText,2);
InFile.Write(TextAll);
InFile.Close();

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.

Это сообщение посчитали полезным следующие участники:

Отправлено: 14:54, 24-08-2018 | #22


Ветеран


Сообщения: 27449
Благодарности: 8088

Профиль | Отправить PM | Цитировать


megaloman, если пользовать JScript, то удобнее регуляркой.

Отправлено: 15:30, 24-08-2018 | #23


Ветеран


Contributor


Сообщения: 2735
Благодарности: 1699

Профиль | Отправить PM | Цитировать


Цитата Iska:
если пользовать JScript, то удобнее регуляркой »
в этой задаче - какая в них радость?

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Отправлено: 16:33, 24-08-2018 | #24


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1235
Благодарности: 517

Профиль | Отправить PM | Цитировать


Цитата megaloman:
Не грубите писателю, он пишет как умеет »


Цитата megaloman:
без некошерного создания второго файла »
Цитата megaloman:
длинный код »
тогда кошерный и короткий powershell:
Код: Выделить весь код
(gc test.txt -raw) -replace '(?<=^|\n)[^\n]*192\.168\.1\.101[^\n]*\n'|sc test.txt -non


Цитата megaloman:
какая в них радость? »
код будет значительно короче...

-------
scio me nihil scire. Ѫ


Последний раз редактировалось YuS_2, 24-08-2018 в 17:06.


Отправлено: 16:56, 24-08-2018 | #25


Ветеран


Сообщения: 27449
Благодарности: 8088

Профиль | Отправить PM | Цитировать


Цитата megaloman:
в этой задаче - какая в них радость? »
В использовании одного .test() и одного .replace(). Это ведь вроде как должно быть проще, не?


Цитата YuS_2:
тогда кошерный и короткий powershell: »
Я таки ратую за присутствие в коде аналога .test() — ::IsMatch(), дабы не переписывать файл при отсутствии замен.

Отправлено: 19:46, 24-08-2018 | #26


Ветеран


Contributor


Сообщения: 2735
Благодарности: 1699

Профиль | Отправить PM | Цитировать


Iska, Я делал задачу для случая, когда искомая подстрока входит в строку, которую надо удалить. Строка в любом месте текста, может быть первая, может быть последняя. Реплейс, конечно, заманчиво, но не сообразил, как нарисовать регулярку, напряжно ...
Как альтернатива, читать текст построчно

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Отправлено: 19:55, 24-08-2018 | #27


Ветеран


Сообщения: 27449
Благодарности: 8088

Профиль | Отправить PM | Цитировать


Я Вам нарисую, но только для VBScript, без файла и без каких-либо проверок, а Вы сами тогда на JScript переведёте, лады? Мой JScript оставляет желать лучшего.
Код: Выделить весь код
Option Explicit

Dim strContent


strContent = _
	"192.168.1.98" & vbCrLf & _
	"192.168.1.99" & vbCrLf & _
	"192.168.1.100" & vbCrLf & _
	"192.168.1.101" & vbCrLf & _
	"#####192.168.1.101" & vbCrLf & _
	"192.168.1.101#####" & vbCrLf & _
	"#####192.168.1.101#####" & vbCrLf & _
	"192.168.1.102" & vbCrLf & _
	"192.168.1.103" & vbCrLf & _
	"192.168.1.104" & vbCrLf

WScript.Echo _
	"--- Before: -----------------------------" & vbCrLf & _
	strContent & vbCrLf & _
	"-----------------------------------------" & vbCrLf

With WScript.CreateObject("VBScript.RegExp")
	.Pattern = "^.*192\.168\.1\.101.*$\n"
	.Global = True
	.MultiLine = True
	
	If .Test(strContent) Then
		strContent = .Replace(strContent, "")
		
		WScript.Echo _
			"--- After: ------------------------------" & vbCrLf & _
			strContent & vbCrLf & _
			"-----------------------------------------" & vbCrLf
	Else
		WScript.Echo "Not found pattern [" & .Pattern & "]."
	End If
End With

WScript.Quit 0
Скрытый текст


P.S. Не сработает только для одного случая — когда «192.168.1.101» будет в последней строке, и эта строка не будет завершаться символами конца строки.
Это сообщение посчитали полезным следующие участники:

Отправлено: 20:30, 24-08-2018 | #28


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1235
Благодарности: 517

Профиль | Отправить PM | Цитировать


Цитата Iska:
Я таки ратую за присутствие в коде »
понимаю, принимаю и всегда только за... это ведь несложно организовать, ежели возникнет такая необходимость, например так:
Код: Выделить весь код
$re = '(?<=\A|\n)[^\n]*192\.168\.1\.101[^\n]*(\n|\Z)'
if(($a = gc test.txt -raw) -match $re){$a -replace $re|sc test.txt -non}
Цитата Iska:
Не сработает только для одного случая — когда «192.168.1.101» будет в последней строке »
Кстати, да, у меня тоже не было учтено...
Но PCRE-совместимые регулярки - вещь в себе, т.е. достаточно универсальны, в основном...
Этот момент легко решается с помощью \Z

Цитата megaloman:
Реплейс, конечно, заманчиво, но не сообразил, как нарисовать регулярку, напряжно ...
Как альтернатива, читать текст построчно »
Можете взять за основу шаблон из версии для PoSh...
Читать и парсить текст построчно, при достаточно большом объеме - тоскливое занятие (по скорости), хоть и более привлекательное, с точки зрения настраиваемости обработки.

-------
scio me nihil scire. Ѫ


Последний раз редактировалось YuS_2, 24-08-2018 в 22:43.

Это сообщение посчитали полезным следующие участники:

Отправлено: 22:35, 24-08-2018 | #29


Ветеран


Contributor


Сообщения: 2735
Благодарности: 1699

Профиль | Отправить PM | Цитировать


Iska, прочесть файл в строку, добавить конец строки в конец, обработать, что получилось - записать без последнего символа. Всё отработает, но задачка получается очень частная: в моём тупом подходе - я даю скрипту подстроку произвольного вида. Если делать регулярку - получаем частное решение. Но красивое.
Наверное, если передавать js (=vbs) скрипту не подстроку для поиска, а рег. выражение, то прокатит.

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Последний раз редактировалось megaloman, 24-08-2018 в 22:53.


Отправлено: 22:40, 24-08-2018 | #30



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - findstr при записи в тот же файл

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Выключается при выполнении memtest Neschur Непонятные проблемы с Железом 2 16-09-2015 00:02
Медиа - Ошибка при выполнении приложения-сервера при открытии мультимедийных файлов Никон_Стадник@vk Microsoft Windows 7 2 01-02-2013 11:22
Лишний сайт при открытии браузер korobka_dv Лечение систем от вредоносных программ 1 06-12-2012 00:45
Ошибка - Ошибка при выполнении cmd KvoD Microsoft Windows 2000/XP 6 26-12-2010 21:55
[решено] Лишний диалог при установке Win2003 S32 Автоматическая установка Windows 2000/XP/2003 3 29-03-2007 13:28




 
Переход