Jump to content

Recommended Posts


Yes, you do. By using sed (and perhaps unix2dos to correct the line terminators depending on the implementation of sed you choose) almost any modification one can conceieve, however complex, can be performed fast. I put yanklines together to remove dupes fast, in a file, which is very far from the things sed does well. But while you want to reformat individual lines, one by one, no other tool is needed since sed is very powerful and time-proven. sed can be used as a filter, just like FIND.

# delete leading whitespace (spaces, tabs) from front of each line
# aligns all text flush left
sed 's/^[ \t]*//' # see note on '\t' at end of file

<...>
USE OF '\t' IN SED SCRIPTS: For clarity in documentation, we have used
the expression '\t' to indicate a tab character (0x09) in the scripts.
However, most versions of sed do not recognize the '\t' abbreviation,
so when typing these scripts from the command line, you should press
the TAB key instead. '\t' is supported as a regular expression
metacharacter in awk, perl, and HHsed, sedmod, and GNU sed v3.02.80.

Reference: sed1liners

Link to comment
Share on other sites

I need to deal with specific lines and at the moment I don't know of any better way then the one I used above.
Depending upon poison characters, and using a cmd file, simply using a CALL may be all you need.
FOR /F "DELIMS=" %%# IN (1.INF) DO CALL :SUB %%#
GOTO :EOF
:SUB
>>TEMP.TXT ECHO=%*

Link to comment
Share on other sites

Depending upon poison characters, and using a cmd file, simply using a CALL may be all you need.

FOR /F "DELIMS=" %%# IN (1.INF) DO CALL :SUB %%#
GOTO :EOF
:SUB
>>TEMP.TXT ECHO=%*

You're right :w00t:

There are sometimes comments present:

SystemRoot.Files=10             ; %windir% (replace if exist)

so this seems to work perfectly:

FOR /F "DELIMS=;" %%# IN (1.INF) DO CALL :SUB %%#
GOTO :EOF
:SUB
>>TEMP.TXT ECHO=%*

Thank you.

Edit: Actually it's still not perfect. This gets broken:

Source:

TSClientDefault.Files=65618,%TSCLIENTDIR%

Result:

TSClientDefault.Files=65618,

Edited by tomasz86
Link to comment
Share on other sites

  • 1 month later...

This is a "minified" version of the silent yanklines script which is created on the fly from commandline:

ECHO>yanklines.vbs ^If WScript.Arguments.Count ^<^> 2 then
ECHO>>yanklines.vbs WScript.Quit
ECHO>>yanklines.vbs end ^If
ECHO>>yanklines.vbs Const ForReading=1, ForWriting=2
ECHO>>yanklines.vbs Dim i,j
ECHO>>yanklines.vbs Set objFSO=CreateObject("Scripting.FileSystemObject")
ECHO>>yanklines.vbs Set objInputFile=objFSO.OpenTextFile(WScript.Arguments.Item(0),ForReading)
ECHO>>yanklines.vbs Set objOutputFile=objFSO.OpenTextFile (WorkingDir ^& WScript.Arguments.Item(1),ForWriting,True)
ECHO>>yanklines.vbs Set objDict=CreateObject("Scripting.Dictionary")
ECHO>>yanklines.vbs objDict.CompareMode=1
ECHO>>yanklines.vbs j=0
ECHO>>yanklines.vbs On Error Resume Next
ECHO>>yanklines.vbs While Not objInputFile.AtEndOfStream
ECHO>>yanklines.vbs arrinputRecord=split(objInputFile.Readline,"vbNewLine")
ECHO>>yanklines.vbs strFirstField=arrinputRecord(0)
ECHO>>yanklines.vbs ^If objDict.Exists(strFirstField) then
ECHO>>yanklines.vbs j=j+1
ECHO>>yanklines.vbs Else
ECHO>>yanklines.vbs objDict.add strFirstField,strFirstField
ECHO>>yanklines.vbs End ^If
ECHO>>yanklines.vbs Wend
ECHO>>yanklines.vbs colKeys=objDict.Keys
ECHO>>yanklines.vbs For Each strKey in colKeys
ECHO>>yanklines.vbs objOutputFile.writeline objDict.Item(strKey)
ECHO>>yanklines.vbs Next
ECHO>>yanklines.vbs objInputFile.Close
ECHO>>yanklines.vbs objOutputFile.Close

Maybe someone will fine it useful.

Link to comment
Share on other sites

This is a "minified" version of the silent yanklines script which is created on the fly from commandline:

....

Maybe someone will fine it useful.

IMHO this is - besides smaller - "plainer":

1.000 bytes instead of 1.356 BUT including 10 bytes for the "@ECHO OFF", so actually 366 bytes smaller or almost 27% smaller :w00t:;).

@ECHO OFF&(
ECHO ^If WScript.Arguments.Count ^<^> 2 then
ECHO WScript.Quit
ECHO end ^If
ECHO Const ForReading=1, ForWriting=2
ECHO Dim i,j
ECHO Set objFSO=CreateObject^("Scripting.FileSystemObject"^)
ECHO Set objInputFile=objFSO.OpenTextFile^(WScript.Arguments.Item^(0^),ForReading^)
ECHO Set objOutputFile=objFSO.OpenTextFile ^(WorkingDir ^& WScript.Arguments.Item^(1^),ForWriting,True^)
ECHO Set objDict=CreateObject^("Scripting.Dictionary"^)
ECHO objDict.CompareMode=1
ECHO j=0
ECHO On Error Resume Next
ECHO While Not objInputFile.AtEndOfStream
ECHO arrinputRecord=split^(objInputFile.Readline,"vbNewLine"^)
ECHO strFirstField=arrinputRecord^(0^)
ECHO ^If objDict.Exists^(strFirstField^) then
ECHO j=j+1
ECHO Else
ECHO objDict.add strFirstField,strFirstField
ECHO End ^If
ECHO Wend
ECHO colKeys=objDict.Keys
ECHO For Each strKey in colKeys
ECHO objOutputFile.writeline objDict.Item^(strKey^)
ECHO Next
ECHO objInputFile.Close
ECHO objOutputFile.Close
)>yanklines.vbs

jaclaz

Link to comment
Share on other sites

I believe (1) is very necessary, or or least the "< 2" part is, since I'm not sure what will happen, besides error, if you do not specify both the input and output file. If you have extra arguments, ie "> 2", they will just be ignored but it is an indication that something is screwed up in the program call.

AFAIK, (2) is not "necessary" since both files "should" be closed when the script exits, but it is best practice and I would always do it. You should always try to clean up after yourself, and not depend on what "should" happen. But that's just my opinion.

Cheers and Regards

Edited by bphlpt
Link to comment
Share on other sites

I'm wondering if these lines are absolutely necessary:

2.

objInputFile.Close
objOutputFile.Close

The script seems to work without them too...

Removing these lines you'd be introducing a potential bug by relying on behavior which is not guaranteed.

And running a large number of times such a buggy script may lead to all kinds of hard to debug conditions.

Don't ever forget to close all open files before terminating.

Link to comment
Share on other sites

I believe (1) is very necessary, or or least the "< 2" part is, since I'm not sure what will happen, besides error, if you do not specify both the input and output file. If you have extra arguments, ie "> 2", they will just be ignored but it is an indication that something is screwed up in the program call.

I don't get it. :unsure:

That would be a check to make sure that exactly 2 arguments are passed to the script, if the script is invoked only from a batch and only with the correct 2 arguments there is no need for that check (which should be made BEFORE in the calling batch).

Or am I missing something?

jaclaz

Link to comment
Share on other sites

Removing these lines you'd be introducing a potential bug by relying on behavior which is not guaranteed.

And running a large number of times such a buggy script may lead to all kinds of hard to debug conditions.

Don't ever forget to close all open files before terminating.

What do you mean by "closing" files?

This is how I use the script:

(
ECHO ^If WScript.Arguments.Count ^<^> 2 then
ECHO WScript.Quit
ECHO end ^If
ECHO Const ForReading=1, ForWriting=2
ECHO Dim i,j
ECHO Set objFSO=CreateObject^("Scripting.FileSystemObject"^)
ECHO Set objInputFile=objFSO.OpenTextFile^(WScript.Arguments.Item^(0^),ForReading^)
ECHO Set objOutputFile=objFSO.OpenTextFile ^(WorkingDir ^& WScript.Arguments.Item^(1^),ForWriting,True^)
ECHO Set objDict=CreateObject^("Scripting.Dictionary"^)
ECHO objDict.CompareMode=1
ECHO j=0
ECHO On Error Resume Next
ECHO While Not objInputFile.AtEndOfStream
ECHO arrinputRecord=split^(objInputFile.Readline,"vbNewLine"^)
ECHO strFirstField=arrinputRecord^(0^)
ECHO ^If objDict.Exists^(strFirstField^) then
ECHO j=j+1
ECHO Else
ECHO objDict.add strFirstField,strFirstField
ECHO End ^If
ECHO Wend
ECHO colKeys=objDict.Keys
ECHO For Each strKey in colKeys
ECHO objOutputFile.writeline objDict.Item^(strKey^)
ECHO Next
ECHO objInputFile.Close
ECHO objOutputFile.Close
)>TEMP\yanklines.vbs
FOR /F "tokens=* delims=" %%I IN ('DIR/B/S "%SPLITDIR%"') DO (
START "yanklines" /WAIT TEMP\yanklines.vbs "%%I" "TEMP\temp.txt"
MOVE "TEMP\temp.txt" "%%I"
)

Link to comment
Share on other sites

I believe (1) is very necessary, or or least the "< 2" part is, since I'm not sure what will happen, besides error, if you do not specify both the input and output file. If you have extra arguments, ie "> 2", they will just be ignored but it is an indication that something is screwed up in the program call.

I don't get it. :unsure:

That would be a check to make sure that exactly 2 arguments are passed to the script, if the script is invoked only from a batch and only with the correct 2 arguments there is no need for that check (which should be made BEFORE in the calling batch).

Or am I missing something?

jaclaz

You are absolutely correct, of course, as long as the assumption is assured. I think both Den and I were looking at the code snippet from a "stand-alone" perspective, or as a function you might paste into another piece of code or share with someone else. No comment was made in the last few posts as to any assumptions or requirements, either before or after yanklines.vbs is invoked, so not knowing if the proper error checking had been done before the function was called ...

Removing these lines you'd be introducing a potential bug by relying on behavior which is not guaranteed.

And running a large number of times such a buggy script may lead to all kinds of hard to debug conditions.

Don't ever forget to close all open files before terminating.

What do you mean by "closing" files?

He's talking about

objInputFile.Close
objOutputFile.Close

Cheers and Regards

Edited by bphlpt
Link to comment
Share on other sites

Slightly bigger but allows to copy and paste the script "as is" (without any need for carets) at the END of the batch....

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS

FOR /F "tokens=1 delims=[]" %%A in ('FIND /N "::THIS IS START OF VBS SCRIPT::" %~dpnx0') DO SET More_offset=%%A
ECHO 'Hi I am yanklines.vbs script>yanklines.vbs
FOR /F "tokens=*" %%A IN ('MORE +%More_offset% %~dpnx0') DO ECHO %%A>>yanklines.vbs
ECHO do whatever the batch is supposed to do
GOTO :EOF

::THIS IS START OF VBS SCRIPT::
If WScript.Arguments.Count <> 2 then
WScript.Quit
end If
Const ForReading=1, ForWriting=2
Dim i,j
Set objFSO=CreateObject("Scripting.FileSystemObject")
Set objInputFile=objFSO.OpenTextFile(WScript.Arguments.Item(0),ForReading)
Set objOutputFile=objFSO.OpenTextFile (WorkingDir & WScript.Arguments.Item(1),ForWriting,True)
Set objDict=CreateObject("Scripting.Dictionary")
objDict.CompareMode=1
j=0
On Error Resume Next
While Not objInputFile.AtEndOfStream
arrinputRecord=split(objInputFile.Readline,"vbNewLine")
strFirstField=arrinputRecord(0)
If objDict.Exists(strFirstField) then
j=j+1
Else
objDict.add strFirstField,strFirstField
End If
Wend
colKeys=objDict.Keys
For Each strKey in colKeys
objOutputFile.writeline objDict.Item(strKey)
Next
objInputFile.Close
objOutputFile.Close

jaclaz

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...