我需要一些帮助来创建一个循环,该循环将使用我的文件扩展名.tar.gz
解压缩它,并使用grep -a >> output.text搜索其中的文件(扩展名为.tlg)。

在outout.text中,我需要匹配的数据以及文件名和它来自的父tar。

已经执行了此搜索,我希望删除未压缩的文件,并继续对下一个tar文件进行操作,直到检查完所有tar。

我无法一次全部解压缩,因为我没有足够的磁盘空间

谁能帮忙


谢谢

最佳答案

为了避免创建临时文件,可以使用GNU tar的--to-stdout选项。

下面的代码对路径中的空格和其他字符可能会引起外壳混淆的情况进行了谨慎处理:

#! /usr/bin/perl

use warnings;
use strict;

sub usage { "Usage: $0 pattern tar-gz-file ..\n" }

sub output_from {
  my($cmd,@args) = @_;
  my $pid = open my $fh, "-|";
  warn("$0: fork: $!"), return unless defined $pid;
  if ($pid) {
    my @lines = <$fh>;
    close $fh or warn "$0: $cmd @args exited " . ($? >> 8);
    wantarray ? @lines : join "" => @lines;
  }
  else {
    exec $cmd, @args or die "$0: exec $cmd @args: $!\n";
  }
}

die usage unless @ARGV >= 2;
my $pattern = shift;
foreach my $tgz (@ARGV) {
  chomp(my @toc = output_from "tar", "-ztf", $tgz);
  foreach my $tlg (grep /\.tlg\z/, @toc) {
    my $line = 0;
    for (output_from "tar", "--to-stdout", "-zxf", $tgz, $tlg) {
      ++$line;
      print "$tlg:$line: $_" if /$pattern/o;
    }
  }
}


样品运行:

$ ./grep-tlgs你好tlgs.tar.gz
tlgs / another.tlg:2:您好
tlgs / file1.tlg:2:您好
tlgs / file1.tlg:3:您好
tlgs / third.tlg:1:您好

$ ./grep-tlgs ^ tlgs.tar.gz
tlgs / another.tlg:1:等等等等
tlgs / another.tlg:2:您好
tlgs / another.tlg:3:你好
tlgs / file1.tlg:1:哇
tlgs / file1.tlg:2:您好
tlgs / file1.tlg:3:您好
tlgs / file1.tlg:4:再见
tlgs / third.tlg:1:您好
tlgs / third.tlg:2:您好

$ ./grep-tlgs ^ xtlgs.tar.gz
tar:xtlgs.tar.gz:无法打开:没有此类文件或目录
tar:错误无法恢复:现在退出
tar:孩子返回了状态2
tar:由于先前的错误而以失败状态退出
./grep-tlgs:tar -ztf xtlgs.tar.gz在./grep-tlgs第14行退出了2。

10-06 03:35