Programmatically extract tar.gz in a single step (on Windows with 7-Zip) - scripting

Problem: I would like to be able to extract tar.gz files in a single step. This makes my question almost identical to this one: Stack Overflow question for tar-gz.
My question is almost the same, but not the same, because I would like to do this on windows using 7-Zip command-line (or something similar) inside a bat file or Ruby/Perl/Python script.
Question: This seemingly simple task is proving to be more involved than the first appearance would make it out to be. Does anyone have a script that does this already?

Old question, but I was struggling with it today so here's my 2c. The 7zip commandline tool "7z.exe" (I have v9.22 installed) can write to stdout and read from stdin so you can do without the intermediate tar file by using a pipe:
7z x "somename.tar.gz" -so | 7z x -aoa -si -ttar -o"somename"
Where:
x = Extract with full paths command
-so = write to stdout switch
-si = read from stdin switch
-aoa = Overwrite all existing files without prompt.
-ttar = Treat the stdin byte stream as a TAR file
-o = output directory
See the help file (7-zip.chm) in the install directory for more info on the command line commands and switches.
As noted by #zespri powershell will buffer the input to the second 7z process so can consume a lot of memory if your tar file is large. i.e:
& 7z x "somename.tar.gz" -so | & 7z x -aoa -si -ttar -o"somename"
A workaround from this SO answer if you want to do this from powershell is to pass the commands to cmd.exe:
& cmd.exe '/C 7z x "somename.tar.gz" -so | 7z x -aoa -si -ttar -o"somename"'

7z e example.tar.gz && 7z x example.tar
Use && to combine two commands in one step. Use the 7-Zip portable (you will need 7z.exe and 7z.dll only).

Use the win32 port of tar.
tar -xvfz filename.tar.gz

Since you asked for 7-zip or something similar, I am providing an alternative tool that was written for your exact use case.
The tartool utility is a free and open source tool built using the .NET SharpZipLib library.
Example commmand to extract a .tar.gz / .tgz - file,
C:\>TarTool.exe D:\sample.tar.gz ./
Disclaimer : I am the author of this utility.

As you can see 7-Zip is not very good at this. People have been asking for
tarball atomic operation since 2009. As an alternative, you can use the
Arc program. Example command:
arc unarchive test.tar.gz

Related

ps2pdf - Unable to open initial device

I built a quite large PDF using LaTeX with the lualatex compiler (I need that one because of specific fonts) and now want to shrink the PDF with ps2pdf, following this instruction (the answer with the second-most votes, since gs is not recognized as a command line tool on my computer). My command looks like this:
ps2pdf -dPDFSETTINGS=/ebook -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -q -sOutputFile=output.pdf input.pdf
I get this error message:
MiKTeX GPL Ghostscript 9.25: Device 'pdfwrite' requires an output file but no file was specified.
**** Unable to open the initial device, quitting.
I definitely made sure that the file exists, I tried it using as *.ps file as input, gave the full path, once with and without double-quotes (Windows system), yet nothing worked. Strangely enough, just running ps2pdf ouput.pdf input.ps works, but produces an even larger PDF. What am I missing?
The file that can't be opened is the output file, so if it exists, that would be a potential problem. If 'something else' has the output file open then it won't be possible to write to it.
You appear to be running a non-standard version of Ghostscript, judging by the startup banner, if I were you I would install and use a standard version of Ghostscript, even if you have to build it yourself.
It's odd that 'ps2pdf' which is just a script to run Ghostscript would work, whereas a simple 'gs' would not. I personally would not use the script. Try and find the Ghostscript executable and run that directly.
I'd drop the -q (quiet) switch as well, at least while trying to solve a problem, suppressing messages could be hiding something useful.
Oh I see, you are actually using Windows. Well, the executable on Windows isn't called 'gs', it's called gswin followed by either 32 or 64 for the word size and then c if it's the command line (as opposed to windowed) version. So you want one of gswin32, gswin32c, gswin64 or gswin64c. Note that the Ghostscript installer doesn't add the installation directory to the $PATH environment variable so if you just open a Windows command shell and type 'gswin32c' it won't be found. You need to either add the isntall directory to the $PATH or supply a full path to the executable.
I'd personally use the vanilla Windows binary rather than a modified version supplied under MingW or whatever Linux shell you are using. It's also conceivable that this is causing your problem writing to the output file, if the directory is unavailable, or read-only, to the shell.

Muttrc: how to source a file in muttrc's directory

I have a muttrc file which sources a secondary file mutt-secrets which resides in its same directory. But I have what appear to be two conflicting needs:
Be free to reference the muttrc file from any working directory
Be free to move it (and mutt-secrets) without having to edit muttrc to change the source path for mutt-secrets
At present, the first line of my muttrc says: source mutt-secrets. That works fine when I run mutt from within the directory where the two file reside, but if I run mutt from elsewhere and reference muttrc with a -F flag, then mutt can find muttrc, but muttrc can't find mutt-secrets.
How can I solve this?
Use absolute paths. For example:
source ~/.mutt/mutt-secrets
TL;DR one-line solution:
source `lsof -c mutt -Fn | grep '/muttrc$' | sed 's|^n||; s|/muttrc$||;'`/mutt-secrets
or, if you want to reuse the muttrc directory, you can save it to a custom variable:
set my_muttrc_dir = `lsof -c mutt -Fn | grep '/muttrc$' | sed 's|^n||; s|/muttrc$||'`
source $my_muttrc_dir/mutt-secrets
If you want to see the output of the command when you launch mutt, you can put this line in your muttrc:
echo `lsof -c mutt -Fn | grep '/muttrc$' | sed 's|^n||; s|/muttrc$||'`
Assumptions: the Mutt process is called mutt and the Mutt's initialization file is called muttrc. Furthermore, you could get in trouble if you have more than one Mutt instance running (for example if you launch in parallel two or more Mutt instances with different initialization files, because the command may select the wrong path).
Explanation
The idea is to look for muttrc full path in the list of open files by Mutt. We can get this list using lsof command (it has to be installed in your system), then extract the full path by parsing the lsof output with grep and sed commands.
This approach is viable because Mutt's initialization files support the use of external command's output with backticks (``). When Mutt encounter and execute our command enclosed in backticks (``), it is in the process of reading the muttrc file, so the muttrc file appears in the list of currently open files by Mutt. This enables us to use the lsof command.
lsof parameters
-c mutt: list open files of process named mutt;
-Fn: for each element, print only the name (it is the path in our case). Because of lsof output format, the path will be prefixed with the character n.
grep and sed
We use grep to select the line which contains muttrc file path, assuming the filename is exactly muttrc. Then we clean the lsof output with sed by both removing the n character at the beginning of the line and the /muttrc string from the end of the line. This way we get the path of the directory containing the muttrc file.
There is a cleaner solution?
Mutt expands relative paths inside initialization files from its current working directory, i.e. from the directory you launch Mutt. It supports a mechanism that allows path's expansion relatives to something different, but the "initialization file directory" or something similar are not available. See here.
I neither found a way to get the -F <path> option you pass to the mutt command inside the initialization file.
References
backticks in Mutt's initialization file;
current directory;
_mutt_buffer_expand_path, source code
source_rc, source code
source_rc call, source code
Tested with: Mutt 2.0.5, lsof 4.93.2, GNU grep 3.7, GNU sed 4.7.

How to extract Jester dataset files?

I am trying to extract the dataset given on link:https://20bn.com/datasets/jester
I am unable to extract these file with no extension. I tried using tar and also what they have mentioned on their website, i.e.,
cat 20bn-jester-v1-?? | tar zx
Please assist.
As you can read on the web site:
The video data is provided as one large TGZ archive, split into parts of 1 GB max
so you need to combine the files and the extract.
the command like this can help you:
cat 20bn-jester-v1-??|gzip -dc|tar xf -
cat is used to combine all parts in one file, then gzip to decompress the file and on the end tar to extract the file(s)
I also experienced the same problem for quite some time but I figured out you can use GitBash to unzip the data. just open Gitbash inside the folder where you downloaded the data by right-clicking and selecting gitbash (you must have it installed). then type in the command cat 20bn-jester-v1-?? | tar zx. Press enter and you are done.
First: unzip '*.zip'
Then: cat 20bn-jester-v1-?? | tar zx

how to use CAM::PDF to find + replace from command line

Sorry for the noob question. I just downloaded CAM::PDF along with Strawberry for Windows, and trying to do find/replace from the command line. Ran buidinstalldeps to get all needed prereqs.
I'm trying to run changepagestring.pl from command line. But idk how to reference the file location and have it put the output file for me in a specified location:
changepagestring.pl master-exch-manual.pdf "as shown in Figure" figure output.pdf
My goal is to replace "see above figure" with "figure" in this file. But it's in a different directory than the one I'm in, C:\Users\Me\Doc\CAM-PDF-1.60\
So how do I run and do all this from the command line. I've seen the help file with example, but I get this:
CAM::PDF from command shell with PL file not recognized
There are a few possible solutions. The easiest one from the directory you mentioned is:
perl -Ilib bin/changepagestring.pl ...
Alternatively, if you run the usual Perl install commands from that folder, then changepagestring.pl should be included in your usual path
perl Makefile.PL
make install
Alternatively^2, you can use the "cpan" tool to automate the download, build, test and install steps in one go:
cpan install CAM::PDF

Executing Love2D scripts

The only way I found out to execute my script with the Love2d framework is to zip all of it and then rename the zip to love. This kinds of take a lot of time for a small modification. Is there a faster way to do it? I tried to command line and I get this error
'love' is not recognized as an internal or external command,
operable program or batch file.
LÖVE also executes folders if they have the main.lua in them - you can just drag and drop the folder onto the application, or call it from the command line with the folder as the argument if you prefer.
LÖVE runs the contents of a folder if it can find a main.lua in it (Like Bill said).
[Note that it doesn't check subfolders].
There are three ways to run a love2D program, you can:
a) Drag the folder over the love.exe binary/link (This works in Win and *Nix, I don't know about OS X).
b) Navigate to the directory that is one level above the folder and type love [folder containing main.lua]
or
c) Zip it up and rename the .zip to a .love. Then double click the .love file
Option 'b' will fail if the binary is not in the %PATH%(Windows) or $PATH(*Nix) variable
(It will spout an error message like 'love' is not recognized as an internal or external command, operable program or batch file. on windows and bash: love: command not found on linux).
There are two ways to solve this:
(Both require ADMIN/root privileges, )
1) Add the love binary to the PATH variable. Here's how to do this in windows and in linux (In linux you want to do something like this: PATH=$PATH:$HOME/where/ever/you/put/love/)
2) You can add a link to the love2D binary in C:\WINDOWS\system32 or /usr/bin/.
In windows you create a shortcut to the love.exe (wherever you installed it to) and then drag it into C:\WINDOWS\system32. In linux you can run this:
sudo link /path/to/love/binary /usr/bin/love && sudo chmod ugo+rwx /usr/bin/love
I hope this helps!
Sources:
Google (the links above), Love2D and my knowledge :D
I found this to be very helpful when i started. Hope this helps
A Guide to Getting Started With Love2d
If you're using Mac OS, you should run using:
open -a love xxx.love
To recreate a file as .love, you can run in command line:
zip xxx.love file1.lua file2
If you just want to replace a file in .love:
zip -r xxx.love file1.lua
I think this will make your work easier.
simple way:
create folder /path/to/Game
put your files (main.lua, conf.lua, ...) in folder /path/to/Game
you can run script like this:
love /path/to/Game/
or if you use Linux, you can go in folder (cd /path/to/Game) and type just:
love .
(dot means that you want to run it form in folder
I found a simple solution for save time.
You have to create a file .bat with this simple command:
del Project.love
7z.exe a Project.zip ..\Project\*
ren Project.zip Project.love
For do this you need to download 7zip and insert this file (file.bat) into the folder of your project. Like this:
Good work!
If you're yousing Notepad++ to write your code, just open your main.lua file, then go to Run and add there this text including quotes:
"Path" "$(CURRENT_DIRECTORY)"
Where Path is a Full path to love.exe.
The save it to a key combination and now you can test your code by using this combination in any script at Notepad++.
If you use Sublime Text, you can make a build which runs your application.
https://love2d.org/wiki/Sublime_Text
While in Sublime Text press CMD + B or Ctrl + B