Переименуйте каталог в архиве tar

Начальный нуль на числовой константе в арифметических выражениях оболочки обозначает восьмеричную константу.

Вот портативный способ удалить начальные нули:

h=${h#${h%%[!0]*}}; [ -n "$h" ] || h=0

В ударе, ksh или zsh, можно явно указать основу 10 с $((10#$h)).

14
05.12.2011, 16:03
5 ответов

Это не должно быть очень трудно, по крайней мере, для архивов, которые совместимы с форматом старого стиля, где имена файлов хранятся в фиксированном размере (100 байтов) поле, но я не знаю ни о каком инструменте, который может переименовать файл на месте в архиве tar. Кроме того, со сжатым архивом, необходимо было бы создать новый файл так или иначе.

Это должно быть еще легче, но я не знаю ни о каком существующем инструменте, который может отфильтровать архив, переименовав файлы, когда это идет. Можно создать один сверху библиотек tar в языках сценариев; например, вот сценарий подтверждения концепции для переименования каталога в архиве tar с помощью Perl с Archive::Tar. Архив загружается полностью в память; это - внутреннее ограничение Archive::Tar.

#!/usr/bin/env perl
## Usage: tar-rename OLDPREFIX NEWPREFIX
use strict;
use warnings;
use Archive::Tar;
my ($from, $to) = @ARGV;
my $tar = Archive::Tar->new(\*STDIN);
foreach my $file ($tar->get_files()) {
    my $name = $file->name;
    $name =~ s~\A\Q$from\E($|/)~$to$1~;
    $file->rename($name) unless $name eq $file->name;
}
$tar->write(\*STDOUT);

Tar GNU не имеет способности переименовать участников на лету, но pax (Замена POSIX для cpio и tar) делает. Однако Вы не можете сделать pax оба чтения и запись из архива. То, что можно сделать, подвергают архив как регулярное дерево через AVFS и создают новый архив с pax. Это сохраняет имена файлов (за исключением преобразованного), содержание, времена и режимы, но сбрасывает принадлежность файла Вам (если не выполняется как корень).

mountavfs
cd "~/.avfs$PWD/old.tgz#"
pax -w -s '!bar!baz!' -s '!bar/!baz/' . | gzip >new.tgz
8
27.01.2020, 19:51

И взлом _ сэра и Gilles' ответ выглядят очень хорошими, но если Вашей проблемой является просто название корневого каталога цели tarball, работая rpmbuild, другое решение могло состоять в том, чтобы переопределить %setup макрос, чтобы сделать необходимое переименование dir.

Что-то как (необходимо будет адаптировать и совершенствовать это к фактической конфигурации, в особенности заменяя old-dir и desired-dir и использование правильного инструмента распаковки) это в Вашем ~/.rpmmacros:

%setup cd ../BUILD \
rm -rf cd-player \
bunzip2 -dc ../SOURCES/%{name}-%{version}.tar.bz2 | tar -xvvf - \
if [ $? -ne 0 ]; then \
  exit $? \
fi \
mv <old-dir> <desired-dir> \
cd <desired-dir> \
cd ../BUILD/cd-player \
chmod -R a+rX,g-w,o-w .

Я честно не сделал бы этого, если не в самой экзотической ситуации, но Ваш мог бы иметь место :)

3
27.01.2020, 19:51

Ужасный взлом, но возможно это помогает Вам, дурача tar с символьными ссылками:

$ mkdir a b
$ date >> b/foo
$ tar zcvf b-foo.tgz b/foo
$ rm -rf b
$ ln -s a b

$ tar zxvf b-foo.tgz                                                              
x b/foo: Cannot extract through symlink b
tar: Error exit delayed from previous errors.
$ tar zxvPf b-foo.tgz                                                             
x b/foo
$ ls a
foo

Думая об этом, это, вероятно, не делает, как rpm не позволит Вам смешать с аргументами tar, был бы он? (Редактирование: возможно, некоторые хитрые tar сценарий обертки в $PATH мог получить Вас вокруг этого.)

1
27.01.2020, 19:51

Просто просмотрите эту страницу, но нашел надлежащий ответ в другом месте:

http://www.rpm.org/max-rpm/s1-rpm-inside-macros.html

Это говорит, что можно передать-n %setup макросу, чтобы сказать rpmbuild название высокоуровневой папки в tarball

2
27.01.2020, 19:51

Эта статья была так близка к тому, что мне нужно, но не сигара. Функция переименования внутри Архива ::Tar портила мои папки. Он отлично работал с файлами, но папки выводились без завершающей косой черты (/ ). Пример:

До

$VAR1 = [
          'old_root_folder/',
          'old_root_folder/.dockerignore',
          'old_root_folder/.github/',
.....

После

$VAR1 = [
          'newrootfolder',
          'newrootfolder/.dockerignore',
          'newrootfolder/.github/',
......

Обратите внимание, что корневая папка больше не имеет косой черты! Оказывается, это не имеет значения.Новый архив извлекается без проблем с папками, заканчивающимися косой чертой

.

В итоге я получил следующий фрагмент Perl:

sub renameRootFolderInTar
{
    my $file = shift;
    my $new_root_folder_name = shift;
    my $tar = Archive::Tar->new($file);
    my @files_in_archive = $tar->list_files;
    my $root_folder = @files_in_archive[0]; # whatever they named the root folder in the archive
    $root_folder =~ s/\/$//g;
    foreach(@files_in_archive)
    {
        my $this_archive_file = $_;
        my $dest = $this_archive_file;
        $dest =~ s/^$root_folder\/(.*)/$new_root_folder_name\/$1/g;
        $tar->rename($this_archive_file,$dest);
    }
    my $success = $tar->write( "renamed.tar.gz", COMPRESS_GZIP );
    if($success)
    {
        unlink $file;
        return "renamed.tar.gz";
    }
    else
    {
        print "Sorry, there was a problem when dealing with the raw archive $file:\n";
        print "Could not save renamed.tar.gz\n";
        exit;
    }
}

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

0
19.06.2020, 17:41

Теги

Похожие вопросы