помогите с циклом unix tar и grep

Мне нужна помощь в создании цикла, который возьмет один из моих файлов с расширением .tar.gz, распаковывает его, распаковывает и ищет файлы внутри (с расширением .tlg), используя grep -a >> output.text.

В outout.text мне потребуются совпадающие данные, а также имя файла и родительский tar, из которого он был получен.

После того, как этот поиск был выполнен, я хотел бы, чтобы неиспользованные файлы были удалены, а предварительная обработка продолжалась для следующего файла tar, пока все файлы tar не будут проверены.

Я не могу разархивировать все сразу, так как у меня нет места на диске для этого

Кто-нибудь может помочь?

Благодарность


person matt123    schedule 08.07.2010    source источник


Ответы (2)


Чтобы избежать создания временных файлов, вы можете использовать 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 hello tlgs.tar.gz 
tlgs/another.tlg:2: hello
tlgs/file1.tlg:2: hello
tlgs/file1.tlg:3: hello
tlgs/third.tlg:1: hello
$ ./grep-tlgs ^ tlgs.tar.gz 
tlgs/another.tlg:1: blah blah
tlgs/another.tlg:2: hello
tlgs/another.tlg:3: howdy
tlgs/file1.tlg:1: whoah
tlgs/file1.tlg:2: hello
tlgs/file1.tlg:3: hello
tlgs/file1.tlg:4: good-bye
tlgs/third.tlg:1: hello
tlgs/third.tlg:2: howdy
$ ./grep-tlgs ^ xtlgs.tar.gz 
tar: xtlgs.tar.gz: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now
tar: Child returned status 2
tar: Exiting with failure status due to previous errors
./grep-tlgs: tar -ztf xtlgs.tar.gz exited 2 at ./grep-tlgs line 14.
person Greg Bacon    schedule 08.07.2010

Вы можете перебирать tar, извлекать их, а затем выполнять grep; что-то вроде этого должно работать:

match="somestring"
mkdir out/
for i in *.tar.gz; do
 mkdir out/${i} # create outdir
 tar -C out/${i} -xf ${i} # extract to sub-dir with same name as tar; 
                          # this will show up in grep output
 cd out
 grep -r ${match} ${i} >> ../output.text
 cd ..
 rm -rf out/${i} # delete untarred files
done

будьте осторожны, так как содержимое переменной $i передается в rm -rf и имеет право удалить что-либо навсегда.

person gauteh    schedule 08.07.2010