gpt4 book ai didi

google-apps-script - 如何使用 Google Apps 脚本从 .tar 存档中提取文件

转载 作者:行者123 更新时间:2023-12-01 12:07:48 27 4
gpt4 key购买 nike

大家好,

我正在尝试从 Gmail 获取 tar.gz 附件,解压缩文件并将其保存到 Google 云端硬盘。这是我收到的每日自动生成的报告,由于原始大小 >25mb 而被压缩。

到目前为止我得到了这个:

  var sheet   = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Setup");

var gmailLabels = sheet.getRange("B2:B2").getValue(); //I have my Gmail Label stored here
var driveFolder = sheet.getRange("B5:B5").getValue(); //I have my GDrive folder name stored here

// apply label filter, search only last 24hrs mail
var filter = "has:attachment label:" + gmailLabels + " after:" + Utilities.formatDate(new Date(new Date().getTime()-1*(24*60*60*1000)), "GMT", "yyyy/MM/dd");

var threads = GmailApp.search(filter, 0, 1); // check only 1 email at a time

var folder = DriveApp.getFoldersByName(driveFolder);

if (folder.hasNext()) {
folder = folder.next();
} else {
folder = DriveApp.createFolder(driveFolder);
}


var message = threads[0].getMessages()[0];

var desc = message.getSubject() + " #" + message.getId();
var att = message.getAttachments();

for (var z=0; z<att.length; z++) {
var attName = att[z].getName()
var attExt = attName.search('csv')
if (attExt > 0){ var fileType = "csv"; }
else {
var attExt = attName.search('tar.gz');
if (attExt > 0){ var fileType = "gzip"; }
else {
threads[x].addLabel(skipLabel);
continue;
}
}

// save the file to GDrive
try {
file = folder.createFile(att[z]);
file.setDescription(desc);
}
catch (e) {
Logger.log(e.toString());
}

// extract if gzip
if (fileType == 'gzip' ){
var ungzippedFile = Utilities.ungzip(file);
try {
gz_file = folder.createFile(ungzippedFile);
gz_file.setDescription(desc);
}
catch (e) {
Logger.log(e.toString());
}
}

}

一切正常,但在最后一步中它只解压缩 .gz 文件保存在驱动器中的 .tar 文件。接下来我能用它做什么? .tar 文件包含一个 .csv 文件,我需要在之后提取和处理该文件。

我应该补充一点,我仅限于使用 GAS。

非常感谢任何帮助。

最佳答案

这个答案怎么样?不幸的是,在当前阶段,还没有从 Google Apps 脚本中的 tar 文件中提取文件的方法。不过还好,来自wiki of tar ,我们可以检索 tar 数据的结构。我使用此结构数据通过 Google Apps 脚本实现了此方法。

1。解压 tar 数据:

在运行此脚本之前,请将 tar 文件的文件 ID 设置为 run()。然后,运行 run()

示例脚本:

function tarUnarchiver(blob) {
var mimeType = blob.getContentType();
if (!mimeType || !~mimeType.indexOf("application/x-tar")) {
throw new Error("Inputted blob is not mimeType of tar. mimeType of inputted blob is " + mimeType);
}
var baseChunkSize = 512;
var byte = blob.getBytes();
var res = [];
do {
var headers = [];
do {
var chunk = byte.splice(0, baseChunkSize);
var headerStruct = {
filePath: function(b) {
var r = [];
for (var i = b.length - 1; i >= 0; i--) {
if (b[i] != 0) {
r = b.slice(0, i + 1);
break;
}
}
return r;
}(chunk.slice(0, 100)),
fileSize: chunk.slice(124, 124 + 11),
fileType: Utilities.newBlob(chunk.slice(156, 156 + 1)).getDataAsString(),
};
Object.keys(headerStruct).forEach(function(e) {
var t = Utilities.newBlob(headerStruct[e]).getDataAsString();
if (e == "fileSize") t = parseInt(t, 8);
headerStruct[e] = t;
});
headers.push(headerStruct);
} while (headerStruct.fileType == "5");
var lastHeader = headers[headers.length - 1];
var filePath = lastHeader.filePath.split("/");
var blob = Utilities.newBlob(byte.splice(0, lastHeader.fileSize)).setName(filePath[filePath.length - 1]).setContentTypeFromExtension();
byte.splice(0, Math.ceil(lastHeader.fileSize / baseChunkSize) * baseChunkSize - lastHeader.fileSize);
res.push({fileInf: lastHeader, file: blob});
} while (byte[0] != 0);
return res;
}

// Following function is a sample script for using tarUnarchiver().
// Please modify this to your situation.
function run() {
// When you want to extract the files from .tar.gz file, please use the following script.
var id = "### file ID of .tar.gz file ###";
var gz = DriveApp.getFileById(id).getBlob().setContentTypeFromExtension();
var blob = Utilities.ungzip(gz).setContentTypeFromExtension();

// When you want to extract the files from .tar file, please use the following script.
var id = "### file ID of .tar file ###";
var blob = DriveApp.getFileById(id).getBlob().setContentType("application/x-tar");

// Extract files from a tar data.
var res = tarUnarchiver(blob);

// If you want to create the extracted files to Google Drive, please use the following script.
res.forEach(function(e) {
DriveApp.createFile(e.file);
});

// You can see the file information by below script.
Logger.log(res);
}

2。修改脚本:

如果这个脚本用于你的脚本,例如,这个怎么样?使用上述脚本的 tarUnarchiver()。但我不确定你想如何使用这个脚本。因此,请将此视为示例。

示例脚本:

// extract if gzip
if (fileType == 'gzip' ){
var ungzippedFile = Utilities.ungzip(file);
try {

var blob = ungzippedFile.setContentType("application/x-tar"); // Added
tarUnarchiver(blob).forEach(function(e) {folder.createFile(e.file)}); // Added

}
catch (e) {
Logger.log(e.toString());
}
}
  • 在这个修改后的脚本中,ungzippedFile 的 blob(tar 数据)被放入我的脚本并运行 tarUnarchiver()。然后,将每个文件创建到该文件夹​​。

备注:

  • 当您运行此脚本时,如果出现与 mimeType 相关的错误,请将“tar”的 mimeType 设置为输入 blob。
    • 作为设置 mimeType 的方法,您可以使用如下方法。
      • blob.setContentTypeFromExtension() Ref
      • blob.setContentType("application/x-tar") Ref
    • 它可能已经在 blob 中获得了 mimeType。届时,不需要 setContentTypeFromExtension()setContentType()
  • 如果您想检索每个文件的文件路径,请检查tarUnarchiver() 的响应。您可以从响应中将其视为 fileInf 的属性。

限制:

使用此脚本时,有如下限制。这些限制是由于 Google 的规范。

  • 关于文件大小,当 tar 数据的大小超过 50 MB(52,428,800 字节)时,会发生与大小限制相关的错误。
  • 当提取的文件大小超过 50 MB 时,会发生错误。
  • 当提取文件的单个文件大小接近 50 MB 时,可能会发生错误。
    • 在我的环境中,我可以确认可以提取 49 MB 的大小。但在只有 50 MB 的情况下, 发生错误。

引用:

在我的环境中,我可以确认该脚本有效。但如果这个脚本不起作用,我深表歉意。届时,您能否提供一个示例 tar 文件?我想检查它并修改脚本。

关于google-apps-script - 如何使用 Google Apps 脚本从 .tar 存档中提取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54850028/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com