How do you specify filenames within a zip when creating it on the command line from a pipe?
From what i can gather you cannot do both with the zip
command, i mean you cannot both specify the filenames and pipe the content. You can either pipe the contents and the resulting file is -
or you can pipe the filenames with -@
.
That does not mean that doing so is impossible using other techniques. I outline one of those below. It does mean that you have to have PHP installed and the zip extension loaded.
There could be a whole bunch of other ways to do it. But this is the easiest that I know of. Oh and it's a one-liner too.
This is a working example using PHP
echo contents | php -r '$z = new ZipArchive();$z->open($argv[1],ZipArchive::CREATE);$z->addFromString($argv[2],file_get_contents("php://stdin"));$z->close();' test.zip testfile
To run on windows just swap single and double quotes. Or just place the script in a file.
"test.zip" is the resulting Zip file, "testfile" is the name of the contents that are being piped into the command.
Result from unzip -l test.zip
Archive: test.zip
Length Date Time Name
--------- ---------- ----- ----
6 01-07-2010 12:56 testfile
--------- -------
6 1 file
And here is a working example using python
echo contents | python -c "import sys
import zipfile
z = zipfile.ZipFile(sys.argv[1],'w')
z.writestr(sys.argv[2],sys.stdin.read())
z.close()
" test5.zip testfile2
Result of unzip -l
Archive: test5.zip
Length Date Time Name
-------- ---- ---- ----
9 01-07-10 13:43 testfile2
-------- -------
9 1 file
Result of unzip -p
contents
Can I specify redirects and pipes in variables?
I would do something like this (use bash -c or eval):
zipped=''
zipcommand='>'
if [ "$1" = "-z" ]
then
zipped='zipped '
filename="${filename}.zip"
zipcommand='| zip -@'
fi
echo "Creating ${zipped}patch file $filename..."
eval "svn diff $zipcommand $filename"
# this also works:
# bash -c "svn diff $zipcommand $filename"
This appears to work, but my version of zip (Mac OS X) required that i change the line:
zipcommand='| zip -@'
to
zipcommand='| zip - - >'
Edit: incorporated @DanielBungert's suggestion to use eval
PowerShell partial zip file name
It sounds like you only expect 1 zip file however I tailored this answer around the possibility of having more than 1
- We are going to use
Get-ChildItem
to get any zip files from y:\ that match 'CallRecordings*.zip' - We then pipe these files one at a time to the
ForEach-Object
cmdlet where we- assign the extraction folder
- unzip the file
- and then rename the file.
$i
is used to allow us different names for our renamed zip file in case there are more than 1 being processed.
$i = 0
Get-ChildItem -Path 'Y:\' -Filter 'CallRecording*.zip' | ForEach-Object -Process {
$extractFolder = "C:\temp\$($_.BaseName)"
$_ | Expand-Archive -DestinationPath $extractFolder
# ($? tells us if the last command completed successfully)
if ($?) {
# only rename file if Expand-Archive was successful
$_ | Rename-Item -NewName ((Get-Date).AddDays(-1).ToString('yyyyMMdd') + "_$((++$i)).zip")
}
}
How to create a zip archive with PowerShell?
If you head on over to CodePlex and grab the PowerShell Community Extensions, you can use their write-zip
cmdlet.
Since
CodePlex is in read-only mode in preparation for shutdown
you can go to PowerShell Gallery.
Output Filenames in a Folder to a Text File
In PowerShell:
# Get-ChildItem (gci) is PowerShell's dir equivalent.
# -File limits the output to files.
# .BaseName extracts the file names without extension.
(Get-ChildItem -File).BaseName | Out-File files.txt
Note: You can use dir
in PowerShell too, where it is simply an alias of Get-ChildItem
. However, to avoid confusion with cmd.exe
's internal dir
command, which has fundamentally different syntax, it's better to use the PowerShell-native alias, gci
. To see all aliases defined for Get-ChildItem
, run Get-Alias -Definition Get-ChildItem
Note that use of PowerShell's >
redirection operator - which is effectively an alias of the Out-File
cmdlet - would also result in the undesired inclusion of the output, files.txt
, in the enumeration, as in cmd.exe
and POSIX-like shells such as bash
, because the target file is created first.
By contrast, use of a pipeline with Out-File
(or Set-Content
, for text input) delays file creation until the cmdlet in this separate pipeline segment is initialized[1] - and because the file enumeration in the first segment has by definition already completed by that point, due to the Get-ChildItem
call being enclosed in (...)
, the output file is not included in the enumeration.
Also note that property access .BaseName
was applied to all files returned by (Get-ChildItem ...)
, which conveniently resulted in an array of the individual files' property values being returned, thanks to a feature called member-access enumeration.
Character-encoding note:
In Windows PowerShell,
Out-File
/>
creates "Unicode" (UTF-16LE) files, whereasSet-Content
uses the system's legacy ANSI code page.In PowerShell (Core) 7+, BOM-less UTF-8 is the consistent default.
The -Encoding
parameter can be used to control the encoding explicitly.
[1] In the case of Set-Content
, it is actually delayed even further, namely until the first input object is received, but that is an implementation detail that shouldn't be relied on.
Need to ZIP an entire directory using Node.js
I ended up using archiver lib. Works great.
Example
var file_system = require('fs');
var archiver = require('archiver');
var output = file_system.createWriteStream('target.zip');
var archive = archiver('zip');
output.on('close', function () {
console.log(archive.pointer() + ' total bytes');
console.log('archiver has been finalized and the output file descriptor has closed.');
});
archive.on('error', function(err){
throw err;
});
archive.pipe(output);
// append files from a sub-directory, putting its contents at the root of archive
archive.directory(source_dir, false);
// append files from a sub-directory and naming it `new-subdir` within the archive
archive.directory('subdir/', 'new-subdir');
archive.finalize();
Related Topics
How to Find All the Files That Were Created Today in Unix/Linux
How to Send List of File in a Folder to a Txt File in Linux
Using Rsync Include and Exclude Options to Include Directory and File by Pattern
Sudo: Docker-Compose: Command Not Found
How Much Memory Is Consumed by the Linux Kernel Per Tcp/Ip Network Connection
Grep from Tar.Gz Without Extracting [Faster One]
How to Create Threads Without System Calls in Linux X86 Gas Assembly
Run Bash Commands from Txt File
Export Not Working in My Shell Script
Async Connect and Disconnect with Epoll (Linux)
Centos Through a Vm - No Urls in Mirrorlist
How to Delete Files Older Than Specific Date in Linux
Adding Timestamp to a Filename with Mv in Bash
Help with Understanding a Very Basic Main() Disassembly in Gdb