NSIS: Problem to copy 1 file to another excluding a line - file-io

I want to replace the file 1.txt with its original contents except the line in R1, for which I wrote the following code:
FileOpen $0 "1.txt" "r"
GetTempFileName $R0
FileOpen $1 $R0 "w"
loop:
FileRead $0 $2
IfErrors done
strcmp $R1 $2 loop here
here:
FileWrite $1 $2
Goto loop
done:
FileClose $0
FileClose $1
Delete "1.txt"
CopyFiles /SILENT $R0 "1.txt"
Delete $R0
But its not working properly, it keeps 1.txt as it is. Can somebody please help me to find out where is the problem?

I have just ran into the same problem. Fixed it by inserting a
ClearErrors
command before "loop:"

Related

AWK script ignore first line

I am iterating through a csv file with awk using the command gawk -f script.awk example.csv.
script.awk is a file containing my commands:
BEGIN{FS=","}
pattern {command}
pattern {command}
END{print output}
If I wanted to skip the first line of the csv file, where would I put the NR>1 command in script.awk?
I suggest:
BEGIN{FS=","}
NR==1 {next}
pattern {command}
pattern {command}
END{print output}
From man awk:
next: Stop processing the current input record. Read the next input record and start processing over with the first pattern in the AWK program. Upon reaching the end of the input data, execute any END rule(s).

awk: how to "nextfile" in ENDFILE?

refer to "The GNU Awk User's Guide"
The next statement (see section The next Statement) is not allowed inside either a BEGINFILE or an ENDFILE rule. The nextfile statement is allowed only inside a BEGINFILE rule, not inside an ENDFILE rule.
I have tested "nextfile" in BEGINFILEļ¼š
Even if nextfile is written in BEGINFILE, the corresponding file in ENDFILE will be executed
I wonder how can I skip the "file" that "nextfile" in BEGINFILE
If your question is "can we use nextfile inside ENDFILE section" Then short answer is no, we can't use it.
Here is an example:
Use of nextfile in BEGINFILE section: Let's say we have 2 Input_files named file1 and file2.
Let us run nextfile inside BEGINFILE rule.
awk 'BEGINFILE{print FILENAME;nextfile} 1' file1 file2
file1
file2
We could see its printing Input_file names in it and NOT printing the contents of files, means its working fine.
Use of nextfile inside ENDFILE block: Now lets run nextfile inside ENDFILE section and see what happens.
awk '1;ENDFILE{nextfile;print "bla bla"}' file1 file2
awk: cmd. line:1: error: `nextfile' used in ENDFILE action
It gives an error as you see above. Why this is happening, because ENDFILE OR END blocks always get executed after all the records of Input_file(s) are done with executing, so in case you want to jump to next Input_file then you could either use it in BEGINFILE OR BEGIN section OR use it in main block of your code in case you want to match specific condition and then jump to next Input_file.
How to skip ENDFILE section for a specific Input_file: If you have an ENDFILE statement then on each Input_file's record reading, then to skip a specific Input_file we could use condition like this:
awk '1;ENDFILE{if(FILENAME!="file2"){print FILENAME}}' file1 file2
Output will be as follows.
bla bla bla file1 contents here.....
file1
bla bnla bla file2 contents here....
Basically its print contents of Input_file1 and Input_file2 but because a condition is mentioned in ENDFILE block its NOT printing file2 name in output, hence prevented a statements from execution in ENDFILE block here.
Ideal use of nextfile in BEGINFILE block: If we use nextfile inside BEGINFILE block then it will for sure NOT going to print any of the records of that specific Input_file, why because BEGINFILE block's statements gets executed before reading records from Input_file when we mention nextfile it will NOT start reading records process and will simply jump to next Input_file.
So when to use nextfile in BEGINFILE block?: IMHO one of the BEST use case will be when we want to process multiple Input_file(s) and want to deal with headers for each Input_file(eg--> print only header OR a message for specific file and DO NOT process records of that Input_file). OR 2nd case I could think of if any processing you need to do before executing the records of that Input_file.
If you read the GNU awk manual, then it states this about nextfile:
In gawk, execution of nextfile causes additional things to happen: any ENDFILE rules are executed if gawk is not currently in an END or BEGINFILE rule, ARGIND is incremented, and any BEGINFILE rules are executed.
With gawk, nextfile is useful inside a BEGINFILE rule to skip over a file that would otherwise cause gawk to exit with a fatal error. In this case, ENDFILE rules are not executed.
source: GNU awk manual: nextfile statement
So, what does this mean?
ENDFILE is executed if nextfile is in a normal pattern-action pair (pattern { action })
$ awk '{nextfile}1;ENDFILE{print "processing ENDFILE"}' /dev/random
processing ENDFILE
ENDFILE is executed if nextfile is in a BEGINFILE-block (BEGINFILE { action })
$ awk 'BEGINFILE{print "processing BEGINFILE with error", ERRNO; nextfile}1
ENDFILE{print "processing ENDFILE"}' /dev/random
processing BEGINFILE with error
processing ENDFILE
ENDFILE is not executed if nextfile is in a BEGINFILE-block and an error occurred (BEGINFILE { action })
$ touch foo; chmod -r foo
$ awk 'BEGINFILE{print "processing BEGINFILE with error", ERRNO; nextfile}1
ENDFILE{print "processing ENDFILE"}' foo
processing BEGINFILE with error Permission denied
How can we skip ENDFILE using nextfile?
The answer is to fake an error. By assigning anything to the Gnu variable ERRNO, you will skip the ENDFILE block
$ awk 'BEGINFILE{ERRNO=1; print "processing BEGINFILE with error", ERRNO; nextfile}1
ENDFILE{print "processing ENDFILE"}' /dev/random
processing BEGINFILE with error 1

Gawk Print puzzling behavior

A csv file has two columns.
The code below outputs the entire file (all rows and the two columns separated by a comma)
BEGIN {FS=","}
{print $0}
However, the code below, outputs only one value viz. the Column 1 of the first row:
BEGIN {FS=","}
{print $1}
Above code is a .awk file and run in Windows using the command gawk -f test.awk xyz.csv > output.csv
What am I doing wrong?
Edited:
Output after changing the {Print $1} to "{print "<" NR "><" $1 "><" $0 ">"}"``
<1><naskar><naskar,sahoo ,1
sahoo ,18290,
ree ,6379,
mukherjee ,4609,
Try calling gawk as gawk -v RS='\n' ... since the most likely problem is that you have UNIX line endings (\n) in your input file but your call to gawk is expecting DOS line endings (\r\n) and so thinks the file is a single line. If that's not it then change {print $1} to {print "<" NR "><" $1 "><" $0 ">"} and create a file with 5 lines run the script on it then edit your question to show the input file and the output you get.
Under windows you can create a batchfile like this:
#echo off
powershell -Command "write \"$(\"CRLF:\") - $((Get-Content '%1' -Raw) -match '\r\n$')\""
powershell -Command "write \"$(\"CR:\") - $((Get-Content '%1' -Raw) -match '\r$')\""
powershell -Command "write \"$(\"LF:\") - $((Get-Content '%1' -Raw) -match '\n$')\""
It will output something like this for a file with LF as line separator:
D:\TEMP>file.bat textfile.txt
CRLF: - False
CR: - False
LF: - True
D:\TEMP>

Print lines matching a pattern only if the next line does not match the pattern

I want to use awk to print lines that match a pattern only if the following line does not match the pattern. In this case, the pattern is that the line begins with O. This is what I tried:
awk '!/^O/ {print x}; /^O/ {x=$0}' myfile.txt
This is printing far too many lines though, including printing the lines I specifically do not want to print.
Not tested.
Should probz work
awk '/^O/{if(seen==0){seen=1};c=$0} !/^O/{if (seen==1) {print c; seen=0;}}' myfile.txt
Shortened version
awk '/^O/{x=$0} !/^O/{if(x!=0) {print x; x=0;}}' myfile.txt
More shortening
awk '/^O/{x=$0} !/^O/{if(x){print x;x=0;}}' myfile
Think this is shortest it can go
awk '/^O/{x=$0} !/^O/&&x{print x;x=0;}' myfile
Changed them all because it printed the wrong lines.
also made it shorter :)
awk 'a=/^O/{x=$0} !a&&x{print x;x=0;}' myfile

NSIS Find files in silent mode not working

I have the following function to recursively search for dll files.
Function ProcessDLLFiles
Exch $0
Push $1
Push $2
FindFirst $1 $2 "$INSTDIR\*.dll"
loop:
IfErrors end
DetailPrint 'Found "$0\$2"'
FindNext $1 $2
goto loop
end:
FindClose $1
FindFirst $1 $2 "$0\*.*"
dirloop:
IfErrors dirend
IfFileExists "$0\$2\*.*" 0 dirnext
StrCmp $2 "." dirnext
StrCmp $2 ".." dirnext
Push "$0\$2"
call ${__FUNCTION__}
dirnext:
FindNext $1 $2
goto dirloop
dirend:
FindClose $1
Pop $2
Pop $1
Pop $0
FunctionEnd
When I run the installer normally, it works as expected and finds all dll files in the associated folder.
However, it does not find these files in silent mode, even though I can navigate to the directory it is searching in and see that the files are there. I already request admin privileges during installation, and Administrators have full permissions on the dll files in the folder.
Any ideas why it may not be finding the files?
When calling the nxs plugin to create a banner, needed to use /end parameter.