<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; JScript: удаление повторов строк в файле]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=839</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=839&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «JScript: удаление повторов строк в файле».]]></description>
		<lastBuildDate>Wed, 14 Nov 2007 14:30:06 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[JScript: удаление повторов строк в файле]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=6023#p6023</link>
			<description><![CDATA[<p>Юниксовая команда <strong>uniq</strong> сжимает идущие подряд повторы строк, оставляя в файле повторяющиеся строки, если они идут не подряд. Чтобы она выводила только уникальные строки, приходится сортировать входной файл, что зачастую неприемлемо.<br />Этот скрипт оставляет в выходном файле только одну уникальную строку на весь файл. Порядок строк при этом не нарушается. Файлы целиком в память не грузятся, а обрабатываются построчно. Пустые строки учитываются так же, как и все остальные. Есть 2 режима:<br />/1 - записывать в выходной файл первую встретившуюся строку, прочие дубли отбрасывать<br />/2 - наоборот, записывать последнюю строку из всех повторов, а первые дубли отбрасывать<br />Параметр /i - обработка без учета регистра символов. При запуске без параметров скрипт выдает справку. Разбор командной строки самый простой, поэтому важен порядок следования параметров, и нельзя опускать промежуточные параметры.<br /></p><div class="codebox"><pre><code>var
   WSH = new ActiveXObject (&quot;WScript.Shell&quot;),
   ARG = WScript.Arguments,
   FSO = new ActiveXObject(&quot;Scripting.FileSystemObject&quot;),
   ForReading = 1,
   ForWriting = 2,
   ForAppending = 8,
   buf = new Array(),
   fCountAll=0,
   fCount=0,
   fNumLine,
   fBufLine,
   fInFile,
   fOutFile,
   fInFileName,
   fOutFileName;

// Если скрипт запущен через WScript, перезапускаем его в консоли
if (WScript.FullName.toLowerCase() == (WScript.Path+&#039;\\wscript.exe&#039;).toLowerCase()) {
    var args=&#039;&#039;;
    for (var i=0; i&lt;ARG.length; i++) {
        args+=&#039;&quot;&#039;+ARG(i)+&#039;&quot; &#039;;
    }
    WSH.Run (&#039;cscript.exe &quot;&#039;+WScript.ScriptName+&#039;&quot; &#039;+args);
    WScript.Quit();
}

if ( ARG.length == 0 ) {
   WScript.Echo(&quot;Искусно расширенный и грамотно дополненный аналог UNIX команды uniq.\n&quot;);
   WScript.Echo(&quot;Удаляет из входного файла повторяющеся строки и записывает результат в\nвыходной файл.\n&quot;);
   WScript.Echo(&quot;Файл может быть несортированным.\n\n&quot;);
   WScript.Echo(WScript.ScriptName+&quot; файл [выходной файл [/(1|2) [/i]]]&quot;);
   WScript.Echo(&quot;/1\t1 вариант - записывать первую встретившуюся строку, а прочие дубли\n  \t            отбрасывать&quot;);
   WScript.Echo(&quot;/2\t2 вариант - записывать последнюю строку из всех повторов, а первые\n  \t            дубли отбрасывать&quot;);
   WScript.Echo(&quot;/i\tБез учета регистра символов&quot;);
   WScript.Echo(&quot;\nPress Enter to exit&quot;);
    WScript.StdIn.ReadLine();
   WScript.Quit();
}

fInFileName  = ARG(0);
fOutFileName = ( ARG.length &gt;=2 ) ? ARG(1) : ARG(0)+&quot;.out&quot;
fCond = ((ARG.length &gt;=3 ) ? ((ARG(2) == &quot;/1&quot; ) ? 1 : ((ARG(2) == &quot;/2&quot; )? 2 : 1 ) ) : 1 )
isCaseSensitive = ((ARG.length &gt;=4 ) ? ((ARG(2).toLowerCase() == &quot;/i&quot; ) ? true : false ) : true )

fInFile = FSO.OpenTextFile (fInFileName, ForReading );
fOutFile = FSO.OpenTextFile(fOutFileName, ForWriting, true);


if(fCond == 1) {
   WScript.Echo(&#039;1 вариант - записывать первую встретившуюся строку, а прочие дубли отбрасывать&#039;);

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //
   // здесь записанные строки запоминаются в памяти
   //
   //while (!fInFile.AtEndOfStream) {
   // fBufLine = fInFile.ReadLine();
   // fCountAll++;
   // if (!IsPresent (fBufLine)){      // если текущая строка еще не была записана в выходной файл
   //    fOutFile.WriteLine (fBufLine); // то пишем ее туда
   //    buf.unshift (fBufLine);        // запоминаем что записали
   //    fCount++;
   // }
   //}
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //
   // здесь строки проверяются на присутствие в файле (медленно, но меньше требования к памяти)
   //
   while (!fInFile.AtEndOfStream) {
      fBufLine = fInFile.ReadLine();
      fCountAll++;
      if (!IsPresentInOutput (fBufLine, isCaseSensitive)){      // если текущая строка еще не была записана в выходной файл
         fOutFile.WriteLine (fBufLine); // то пишем ее туда
         fCount++;
      }
      WScript.StdOut.Write(fCountAll+&#039;\r&#039;);
   }
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   WScript.Echo(&#039;Уникальных записей: &#039;+fCount+&#039;, всего: &#039;+fCountAll);

} else if(fCond == 2) {

   WScript.Echo(&#039;2 вариант - записывать последнюю строку из всех повторов, а первые дубли отбрасывать&#039;);

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //
   // здесь строки проверяются на присутствие в файле (медленно, но меньше требования к памяти)
   //
   while (!fInFile.AtEndOfStream) {
      fNumLine = fInFile.Line;      // WScript.Echo(&quot;fNumLine = &quot;+fNumLine);
      fBufLine = fInFile.ReadLine();// WScript.Echo(fBufLine);
      fCountAll++;
      if (!IsPresentInFile (fInFile, fBufLine, isCaseSensitive)) { // если текущая строка уже не встречается в остатке файла
         fOutFile.WriteLine (fBufLine);             // то пишем ее туда
         fCount++;
      }
      fInFile.Close();
      fInFile = FSO.OpenTextFile (ARG(0), ForReading );
      for (var i=0; i&lt;fNumLine; i++) fInFile.SkipLine();
      WScript.StdOut.Write(fCountAll+&#039;\r&#039;);
   }
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   WScript.Echo(&#039;Уникальных записей: &#039;+fCount+&#039;, всего: &#039;+fCountAll);

}



function IsPresentInOutput(fLine, isCaseSens) {
var
   res;
   fOutFile.Close();                                              // закрываем выходной файл, открытый на запись
   fOutFile = FSO.OpenTextFile(fOutFileName, ForReading, true);   // открываем выходной файл на чтение
   res = IsPresentInFile (fOutFile, fLine, isCaseSens);                       // ищем в нем строку
   fOutFile = FSO.OpenTextFile(fOutFileName, ForAppending, true); // открываем выходной файл на добавление
   return res;
}


// проверяет файл от текущей позиции до конца на предмет наличия в нем строки
function IsPresentInFile(fFile, fLine, isCaseSens) {
var
   fTmpStr;
   while (!fFile.AtEndOfStream) {
      //fTmpStr = fFile.ReadLine()
      if (isCaseSens){
         if (fLine == fFile.ReadLine()) return true;
      } else {
         if (fLine.toLowerCase() == fFile.ReadLine().toLowerCase()) return true;
      }
   }
   return (false);
}



function IsPresent(fLine) {
   for (var i = 0; i &lt; buf.length; i++) {
     if (buf[i] == fLine) return (true);
   }
   return (false);
}</code></pre></div><p>Автор скрипта - <strong>delpher</strong>.</p>]]></description>
			<author><![CDATA[null@example.com (The gray Cardinal)]]></author>
			<pubDate>Wed, 14 Nov 2007 14:30:06 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=6023#p6023</guid>
		</item>
	</channel>
</rss>
