J'utilise 7-Zip sous Windows XP et chaque fois que je télécharge un fichier .tar.gz, il me faut deux étapes pour extraire complètement le (s) fichier (s).
Existe-t-il un moyen via le menu contextuel de le faire en une seule étape?
Pas vraiment. Un fichier .tar.gz ou .tgz a deux formats: .tar
est l’archive et .gz
est la compression. Ainsi, la première étape se décompresse et la deuxième extrait l'archive.
Pour tout faire en une seule étape, vous avez besoin du programme tar
. Cygwin inclut ceci.
tar xzvf foobaz.tar.gz
; x = eXtract
; z = filter through gZip
; v = be Verbose (show activity)
; f = filename
Vous pouvez également le faire "en une étape" en ouvrant le fichier dans l'interface graphique de 7-Zip: Ouvrez le fichier .tar.gz
, double-cliquez sur le fichier .tar
inclus, puis extrayez ces fichiers à l'emplacement de votre choix.
Il y a un long fil de discussion ici de personnes demandant/votant pour le traitement en une étape des fichiers tgz et bz2. Le manque d’action jusqu’à présent indique que cela ne se produira que lorsque quelqu'un interviendra et apportera une contribution significative (code, argent, quelque chose).
Vieille question, mais je me débattais avec elle aujourd'hui alors voici mon 2c. L'outil de ligne de commande 7Zip "7z.exe" (j'ai installé la version 9.2.2) peut écrire sur stdout et lire à partir de stdin afin que vous puissiez vous passer du fichier tar intermédiaire en utilisant un tube:
7z x "somename.tar.gz" -so | 7z x -aoa -si -ttar -o"somename"
Où:
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
Voir le fichier d'aide (7-Zip.chm) dans le répertoire d'installation pour plus d'informations sur les commandes et les commutateurs en ligne de commande.
Vous pouvez créer une entrée de menu contextuel pour les fichiers .tar.gz/.tgz qui appelle la commande ci-dessus à l'aide de regedit ou d'un outil tiers, tel que stexbar .
À partir de 7-Zip 9.04, une option de ligne de commande permet d'effectuer l'extraction combinée sans utiliser de stockage intermédiaire pour le fichier plain .tar
:
7z x -tgzip -so theinputfile.tgz | 7z x -si -ttar
-tgzip
est nécessaire si le fichier d'entrée est nommé .tgz
au lieu de .tar.gz
.
Vous utilisez Windows XP, Windows Scripting Host devrait donc être installé par défaut. Cela dit, voici un script WSH JScript pour faire ce dont vous avez besoin. Copiez simplement le code dans un nom de fichier xtract.bat ou quelque chose du genre (peut être ce que vous voulez tant qu'il porte l'extension .bat
) et lancez:
xtract.bat example.tar.gz
Par défaut, le script vérifie le dossier du script, ainsi que la variable d'environnement PATH
de votre système pour 7z.exe. Si vous souhaitez modifier l'apparence des éléments, vous pouvez modifier la variable SevenZipExe en haut du script pour définir le nom de l'exécutable. (Par exemple, 7za.exe ou 7z-real.exe) Vous pouvez également définir un répertoire par défaut pour l'exécutable en modifiant SevenZipDir. Donc, si 7z.exe
est à C:\Windows\system32\7z.exe
, vous devriez mettre:
var SevenZipDir = "C:\\Windows\\system32";
Quoi qu'il en soit, voici le script:
@set @junk=1 /* vim:set ft=javascript:
@echo off
cscript //nologo //e:jscript "%~dpn0.bat" %*
goto :eof
*/
/* Settings */
var SevenZipDir = undefined;
var SevenZipExe = "7z.exe";
var ArchiveExts = ["Zip", "tar", "gz", "bzip", "bz", "tgz", "z", "7z", "bz2", "rar"]
/* Multi-use instances */
var WSH = new ActiveXObject("WScript.Shell");
var FSO = new ActiveXObject("Scripting.FileSystemObject");
var __file__ = WScript.ScriptFullName;
var __dir__ = FSO.GetParentFolderName(__file__);
var PWD = WSH.CurrentDirectory;
/* Prototypes */
(function(obj) {
obj.has = function object_has(key) {
return defined(this[key]);
};
return obj;
})(this.Object.prototype);
(function(str) {
str.trim = function str_trim() {
return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
};
})(this.String.prototype);
(function(arr) {
arr.contains = function arr_contains(needle) {
for (var i in this) {
if (this[i] == needle) {
return true;
}
}
return false;
}
})(this.Array.prototype);
/* Utility functions */
function defined(obj)
{
return typeof(obj) != "undefined";
}
function emptyStr(obj)
{
return !(defined(obj) && String(obj).length);
}
/* WSH-specific Utility Functions */
function echo()
{
if(!arguments.length) return;
var msg = "";
for (var n = 0; n < arguments.length; n++) {
msg += arguments[n];
msg += " ";
}
if(!emptyStr(msg))
WScript.Echo(msg);
}
function fatal(msg)
{
echo("Fatal Error:", msg);
WScript.Quit(1);
}
function findExecutable()
{
// This function searches the directories in;
// the PATH array for the specified file name;
var dirTest = emptyStr(SevenZipDir) ? __dir__ : SevenZipDir;
var exec = SevenZipExe;
var strTestPath = FSO.BuildPath(dirTest, exec);
if (FSO.FileExists(strTestPath))
return FSO.GetAbsolutePathName(strTestPath);
var arrPath = String(
dirTest + ";" +
WSH.ExpandEnvironmentStrings("%PATH%")
).split(";");
for(var i in arrPath) {
// Skip empty directory values, caused by the PATH;
// variable being terminated with a semicolon;
if (arrPath[i] == "")
continue;
// Build a fully qualified path of the file to test for;
strTestPath = FSO.BuildPath(arrPath[i], exec);
// Check if (that file exists;
if (FSO.FileExists(strTestPath))
return FSO.GetAbsolutePathName(strTestPath);
}
return "";
}
function readall(oExec)
{
if (!oExec.StdOut.AtEndOfStream)
return oExec.StdOut.ReadAll();
if (!oExec.StdErr.AtEndOfStream)
return oExec.StdErr.ReadAll();
return -1;
}
function xtract(exec, archive)
{
var splitExt = /^(.+)\.(\w+)$/;
var strTmp = FSO.GetFileName(archive);
WSH.CurrentDirectory = FSO.GetParentFolderName(archive);
while(true) {
var pathParts = splitExt.exec(strTmp);
if(!pathParts) {
echo("No extension detected for", strTmp + ".", "Skipping..");
break;
}
var ext = pathParts[2].toLowerCase();
if(!ArchiveExts.contains(ext)) {
echo("Extension", ext, "not recognized. Skipping.");
break;
}
echo("Extracting", strTmp + "..");
var oExec = WSH.Exec('"' + exec + '" x -bd "' + strTmp + '"');
var allInput = "";
var tryCount = 0;
while (true)
{
var input = readall(oExec);
if (-1 == input) {
if (tryCount++ > 10 && oExec.Status == 1)
break;
WScript.Sleep(100);
} else {
allInput += input;
tryCount = 0;
}
}
if(oExec. ExitCode!= 0) {
echo("Non-zero return code detected.");
break;
}
WScript.Echo(allInput);
strTmp = pathParts[1];
if(!FSO.FileExists(strTmp))
break;
}
WSH.CurrentDirectory = PWD;
}
function printUsage()
{
echo("Usage:\r\n", __file__, "archive1 [archive2] ...");
WScript.Quit(0);
}
function main(args)
{
var exe = findExecutable();
if(emptyStr(exe))
fatal("Could not find 7Zip executable.");
if(!args.length || args(0) == "-h" || args(0) == "--help" || args(0) == "/?")
printUsage();
for (var i = 0; i < args.length; i++) {
var archive = FSO.GetAbsolutePathName(args(i));
if(!FSO.FileExists(archive)) {
echo("File", archive, "does not exist. Skipping..");
continue;
}
xtract(exe, archive);
}
echo("\r\nDone.");
}
main(WScript.Arguments.Unnamed);
Comme vous pouvez le constater, 7-Zip n’est pas très bon à cet égard. Les gens ont demandé tarball opération atomique depuis 2009. Voici un petit programme (490 KB) dans Go qui peut le faire, je l'ai compilé pour vous.
package main
import (
"archive/tar"
"compress/gzip"
"flag"
"fmt"
"io"
"os"
"strings"
)
func main() {
flag.Parse() // get the arguments from command line
sourcefile := flag.Arg(0)
if sourcefile == "" {
fmt.Println("Usage : go-untar sourcefile.tar.gz")
os.Exit(1)
}
file, err := os.Open(sourcefile)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close()
var fileReader io.ReadCloser = file
// just in case we are reading a tar.gz file,
// add a filter to handle gzipped file
if strings.HasSuffix(sourcefile, ".gz") {
if fileReader, err = gzip.NewReader(file); err != nil {
fmt.Println(err)
os.Exit(1)
}
defer fileReader.Close()
}
tarBallReader := tar.NewReader(fileReader)
// Extracting tarred files
for {
header, err := tarBallReader.Next()
if err != nil {
if err == io.EOF {
break
}
fmt.Println(err)
os.Exit(1)
}
// get the individual filename and extract to the current directory
filename := header.Name
switch header.Typeflag {
case tar.TypeDir:
// handle directory
fmt.Println("Creating directory :", filename)
// or use 0755 if you prefer
err = os.MkdirAll(filename, os.FileMode(header.Mode))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
case tar.TypeReg:
// handle normal file
fmt.Println("Untarring :", filename)
writer, err := os.Create(filename)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
io.Copy(writer, tarBallReader)
err = os.Chmod(filename, os.FileMode(header.Mode))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
writer.Close()
default:
fmt.Printf("Unable to untar type : %c in file %s", header.Typeflag,
filename)
}
}
}
7za fonctionne correctement comme ci-dessous:
7za.exe x D:\pkg-temp\Prod-Rtx-Service.tgz -so | 7za.exe x -si -ttar -oD:\pkg-temp\Prod-Rtx-Service