unrar.exe and | pipe on windows - windows

I just downloaded the freeware unrar.exe from winrar website. If, from the command line, you tipe
unrar.exe p -inul myarchive.rar
It "prints" out to default std the content of my archive. Since the archive is just one .avi file, if I do:
unrar.exe p -inul myarchive.rar > output.avi
It works perfectly. Now, I'd need to redirect the output std of this program to the input std on a program of mine. This means that I do:
unrar.exe p -inul myarchive.rar | myprogram.exe
myprogram.exe is just a simple c file that every second (this means: very slowly) reads a char from standard input and prints it to screen.
After approximately 10000 chars, I get only the -1 byte (FF in hexadecimal representation).
Why this? How can I solve this problem?

Related

MS-DOS how to get output of command as variable

I've written a program that returns keycodes as integers for DOS
but i don't know how to get it's output as a variable.
Note: I'm using MS-DOS 7 / Windows 98, so i can't use FOR /F or SET /P
Does anyone know how i could do that?
A few solutions are described by Eric Pement here. However, for older versions of cmd the author was forced to use external tools.
For example, program tools like STRINGS by Douglas Boling, allows for following code:
echo Greetings! | STRINGS hi=ASK # puts "Greetings!" into %hi%
Same goes for ASET by Richard Breuer:
echo Greetings! | ASET hi=line # puts "Greetings!" into %hi%
One of alternative pure DOS solutions needs the program output to be redirected to the file (named ANSWER.DAT in example below) and then uses a specially prepared batch file. To cite the aforementioned page:
[I]n the batch file we need to be able to issue the command
set MYVAR={the contents of ANSWER.DAT go here}. This is a difficult task, since MS-DOS doesn't offer an easy way to prepend "set MYVAR=" to a file [...]
Normal DOS text files and batch files end all lines with two consecutive bytes: a carriage return (Ctrl-M, hex 0D, or ASCII 13) and a linefeed (Ctrl-J, hex 0A or ASCII 10). In the batch file, you must be able to embed a Ctrl-J in the middle of a line.
Many text editors have a way to do this: via a Ctrl-P followed by Ctrl-J (DOS EDIT with Win95/98, VDE), via a Ctrl-Q prefix (Emacs, PFE), via direct entry with ALT and the numeric keypad (QEdit, Multi-Edit), or via a designated function key (Boxer). Other editors absolutely will not support this (Notepad, Editpad, EDIT from MS-DOS 6.22 or earlier; VIM can insert a linefeed only in binary mode, but not in its normal text mode).
If you can do it, your batch file might look like this:
#echo off
:: assume that the datafile exists already in ANSWER.DAT
echo set myvar=^J | find "set" >PREFIX.DAT
copy PREFIX.DAT+ANSWER.DAT VARIAB.BAT
call VARIAB.BAT
echo Success! The value of myvar is: [%myvar%].
:: erase temp files ...
for %%f in (PREFIX.DAT ANSWER.DAT VARIAB.BAT) do del %%f >NUL
Where you see the ^J on line 3 above, the linefeed should be embedded at that point. Your editor may display it as a square box with an embedded circle.

How do I stop bash from adding ^# before each letter in vim

A problem occured for no reason, in a code that worked previously.
There is some data in myfile.csv
MP 0,20,60,200,60,95,100,1,20,50,30,20,20,250,115,200,0,8,85,150,465817
MP 1,17.89,60,200,60,93.945,100,1,20,50,30,20,20,250,115,200,0,10,85,150,465927
MP 2,16.33,60,200,60,93.16,100,1,20,50,30,20,20,250,115,200,0,12,85,150,464987
MP 3,15.12,60,200,60,92.56,100,1,20,50,30,20,20,250,115,200,0,14,85,150,463440
...
I extracted the last 25 lines of my files
tail -n 25 myfile.csv > test1.txt
When I do
cat test1.txt
...
MP 16,20,60,200,60,95,100,1,20,120,30,20,20,250,115,200,0,8,85,150,529469
MP 17,20,60,200,60,95,100,1,20,130,30,20,20,250,115,200,0,8,85,150,534335
no problem... but i want to go in a text editor, every letters is preceded by ^# :
vim test1.txt
^#M^#P^# ^#0^#,^#2^#0^#,^#6^#0^#,^#2^#0^#0^#,^#6^#0^#,^#9^#5^#,^#1^#0^#0^#,^#1^#,^#2^#0^#,^#5^#0^#,^#3^#0^#,^#2^#0^#,^#2^#0^#,^#2^#5^#0^#,^#1^#1^#5^#,^#2^#0^#0^#,^#0^#,^#8^#,^#8^#5^#,^#1^#5^#0^#,^#4^#6^#5^#8^#1^#7^#
and the problem is a want to make a pattern search ( the first word of the line ) that doesn't seem to work because of that
home > awk '/MP 0/{print}' test1.txt
home >
Moreover i would like to put a parameter in my awk :
home > cat mp
0
home > awk "/MP `cat mp`,/{print}" test1.txt
home >
Do you know where does this error comes from ?
thank you
EDIT
The .csv file was saved in Excel 2007 as a "CSV (DOS)"
By saving it as a "CSV" it works => encoding is different
Otherwise, when opening it in vim, do :e ++enc=utf16 to reload the file with the UTF-16 encoding, then (assuming the nullbytes disappeared) do :set fenc=utf-8 and save the file. ( thank you #L3viathan for this answer )
I think your encoding is messed up. Your file was probably saved with the UTF-16 encoding, but for some reason the Byte-Order Mark (0xFEFF) is missing.
After you opened it in vim, do :e ++enc=utf16 to reload the file with the UTF-16 encoding, then (assuming the nullbytes disappeared) do :set fenc=utf-8 and save the file.

Mac versus Windows: End of line and carriage return

This a question about getting Macs and Windows PCs to play nicely with each other.
SCENARIO: I use a Mac. I have a bunch of data files that need some slicing and dicing to use with a visualization toolkit. The visualization software is for Windows only, which is no problem since I have a virtual Windows machine. awk was my tool of choice for this problem, and it generated the input files beautifully. Unfortunately, when I generate the input files for the visualization tool and send them over to the PC, there are no new lines; i.e., on the Mac I open (say) output001.txt:
header.info
# file automatically generated by awk
BEGIN File
...
<columns of data>
...
END File
Looks great, but then I open in on the PC and have:
header.info# file automatically generated by awkBEGIN File...<columns of data>...END File
I understand that Windows and Mac OS treat end of line characters differently. I've read that \n on a Mac stands for newline AND character return whereas Windows treats them separately, necessitating \n\r. But here, the problem is somewhat different. I never used a \n character generating the text file -- awk did all the newlines.
Is there a character that I can have awk put at the end of each line it writes so that Windows will understand where the newlines go?
Sure, make the "Output Record Separator" a Carriage Return plus Linefeed. So instead of
seq 1 10 | awk '1' | cat -vet
1$
2$
3$
4$
5$
6$
7$
8$
9$
10$
use
seq 1 10 | awk '1' ORS='\r\n' | cat -vet
1^M$
2^M$
3^M$
4^M$
5^M$
6^M$
7^M$
8^M$
9^M$
10^M$
Notes:
seq 1 10 just generates the numbers from 1 to 10.
1 amounts to true in awk which means it should just do its default thing - which means to just print the current line.
I just use cat -vet to show the Carriage Returns, i.e ^M.

PDF to JPEG conversion using Ghostscript

I'm using Ghostscript to convert my PDF files to JPEGs with Ghostscript which works great.
For my output images I'm using %03d in the file name, so the file names come out 001, 002 ... and so on according to the page numbers.
But i want in some case the numbers to start from an higher number.
For example I process a file with two pages so the output images are page001.jpg, page002.jpg
Now I want to process another PDF and instead of replacing those files, I want to create page003.jpg, page004.jpg.
How can this be done?
This is my full command line I'm using now:
'C:\gs\gs9.14\bin \gswin64c -dNOPAUSE -sDEVICE=png16m \
-sOutputFile=page-%03d.jpg -r100x100 -q' . $pdf_file. '-c quit'
Here is a workaround trick, that you could use:
gswin64c.exe ^
-sDEVICE=png16m ^
-sOutputFile=page-%03d.jpg ^
-r100x100 ^
-c "showpage showpage" ^
-f filename.pdf
The -c "showpage showpage" inserts two empty pages into the output. The output files will be named
page-001.jpg + page-002.jpg + page-003.jpg + page-004.jpg
So the first two are white-only JPEGs and should be deleted afterwards.
You can extend this command with any number of empty pages you want.
Update
Of course, if you know in advance that you want to convert several different PDF files to images where you want the counting for a new PDF to continue exactly from where the last PDF ended, you could do this:
gswin64c.exe ^
-sDEVICE=jpeg ^
-sOutputFile=page-%03d.jpg ^
-r100x100 ^
-f file1.pdf ^
-f file2.pdf ^
-f file3.pdf ^
-f [...]
BTW, your original command requests .jpg file suffixes, while the Ghostscript device is png16m. This doesn't match. Initially I blindly copied your command, but now I've corrected it.
You cannot do that with the standard version of Ghostscript, the output file numbers are given as the emitted page number (so if you had a 10 page file, with /NumCOpies 2, you would get files numbered 0 to 19).
Of course, you can process the two files on the same command line, I think that will give you the second file with page numbers beginning where the first set left off.
Otherwise you will have to modify the source code of the Ghostscript device.

Extracting a 7-Zip file "silently" - command line option

I want to extract a 7-Zip archive in a Python script. It works fine except that it spits out the extraction details (which is huge in my case).
Is there a way to avoid this verbose information while extracting? I did not find any "silent" command line option to 7z.exe.
My command is
7z.exe -o some_dir x some_archive.7z
I just came across this when searching for the same, but I solved it myself! Assuming the command is processed with Windows / DOS, a simpler solution is to change your command to:
7z.exe -o some_dir x some_archive.7z > nul
That is, direct the output to a null file rather than the screen.
Or you could pipe the output to the DOS "find" command to only output specific data, that is,
7z.exe -o some_dir x some_archive.7z | FIND "ing archive"
This would just result in the following output.
Creating archive some_archive.7z
or
Updating archive some_archive.7z**
My final solution was to change the command to
... some_archive.7z | FIND /V "ing "
Note double space after 'ing'. This resulted in the following output.
7-Zip 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
Scanning
Updating some_archive.7z
Everything is Ok
This removes the individual file processing, but produces a summary of the overall operation, regardless of the operation type.
One possibility would be to spawn the child process with popen, so its output will come back to the parent to be processed/displayed (if desired) or else completely ignored (create your popen object with stdout=PIPE and stderr=PIPE to be able to retrieve the output from the child).
Like they said, to hide most of the screen-filling messages you could use ... some_archive.7z | FIND /V "Compressing" but that "FIND" would also remove the error messages that had that word. You would not be warned. That "FIND" also may have to be changed because of a newer 7-zip version.
7-zip has a forced verbose output, no silence mode, mixes stderr and stdout(*), doesn't save Unix permissions, etc. Those anti-standards behaviors together put "7-zip" in a bad place when being compared to "tar+bzip2" or "zip", for example.
(*) "Upstream (Igor Pavlov) does not want to make different outputs for messages, even though he's been asked several times to do so :(" http://us.generation-nt.com/answer/bug-346463-p7zip-stdout-stderr-help-166693561.html - "Igor Pavlov does not want to change this behaviour" http://sourceforge.net/tracker/?func=detail&aid=1075294&group_id=111810&atid=660493
7zip does not have an explicit "quiet" or "silent" mode for command line extraction.
One possibility would be to spawn the child process with popen, so its output will come back to the parent to be processed/displayed (if desired) or else completely ignored (create your popen object with stdout=PIPE and stderr=PIPE to be able to retrieve the output from the child).
Otherwise Try doing this:
%COMSPEC% /c "%ProgramFiles%\7-Zip\7z.exe" ...
Expanding on #Matthew 's answer and this answer https://superuser.com/questions/194659/how-to-disable-the-output-of-7-zip
I'm using FINDSTR instead of find so I can chain multiple lines to exclude and blank lines as well:
7za.exe a test1.zip .\foldertozip | FINDSTR /V /R /C:"^Compressing " /C:"Igor Pavlov" /C:"^Scanning$" /C:"^$" /C:"^Everything is Ok$"
/V: exclude
/R: regex
/C:"^Compressing " : begining of line, Compressing, 2 spaces
/C:"^Scanning$" : the word Scanning on its own on a line (begining/end)
/C:"^$" : a begining and end without anything in between, ie, a blank line
I'm using /C so that a space is a space, otherwise it's a separator between multiple words to exlude as in this simpler version:
FINDSTR /V "Compressing Pavlov Scanning Everytyhing"
(the same caveats exist, if the wording changes in a new version, or if a useful line starts with the word "Compressing ", it will not work as expected).
If you're running 7-zip.exe from Powershell, and you only want to see errors, then you could try something like this:
7-zip.exe u <Target> <Source> | Select-String "Error" -Context 10
This will only display the "Error" message line and the surrounding 10 lines (or whatever number) to capture the error specific output.
The | FIND is a good alternative to show what happened without displaying insignificant text.
Examining 7zip source I found hidden -ba switch that seems to do the trick. Unfortunately it is not finished. I managed to make it work with several modifications of sources but it's just a hack. If someone's interested, the option variable is called options.EnableHeaders and changes are required in CPP/7zip/UI/Console/Main.cpp file.
Alternatively you can poke 7Zip's author to finish the feature in tracker. There are several requests on this and one of them is here.
7-zip has not such an option. Plus the lines printed at each file compressed are supposed to display at the same spot without newline, erasing the previous one, which has a cool effect. Unfortunatly, in some contexts (Jenkins...) it produced several lines ☹️ flooding the console.
NUL (windows) is maybe one solution.
7-zip.exe -o some_dir x some_archive.7z>NUL
To show just the last 4 lines...
7z x -y some_archive.7z | tail -4
gives me:
Everything is Ok
Size: 917519
Compressed: 171589
The switch -y is to answer yes to everything (in my case to override existing files).
On Unix-like operating systems (Linux, BSD, etc.) the shell command 7z ... >/dev/null will discard all text written by 7z to standard output. That should cover all the status/informational messages written by 7z.
It seems that 7z writes error messages to standard error so if you do >/dev/null, error messages will still be shown.
As told by Fr0sT above, -ba switch outputs only valid things (at least in list option on which I was trying).
7z.exe l archive_name.zip
7z.exe l -ba archive_name.zip
made great difference, esp for parsing the output in scripts.
There is no need to modify anything, just use -ba switch in version19. This was also told bysomeone above. I'm putting as answer as I can't comment.
You can stop 7-Zip from displaying prompts by using the -y switch. This will answer yes to all prompts. Use this only when you are confident.

Resources