Начальный нуль на числовой константе в арифметических выражениях оболочки обозначает восьмеричную константу.
Вот портативный способ удалить начальные нули:
h=${h#${h%%[!0]*}}; [ -n "$h" ] || h=0
В ударе, ksh или zsh, можно явно указать основу 10 с $((10#$h))
.
Это не должно быть очень трудно, по крайней мере, для архивов, которые совместимы с форматом старого стиля, где имена файлов хранятся в фиксированном размере (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
И взлом _ сэра и 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 .
Я честно не сделал бы этого, если не в самой экзотической ситуации, но Ваш мог бы иметь место :)
Ужасный взлом, но возможно это помогает Вам, дурача 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
мог получить Вас вокруг этого.)
Просто просмотрите эту страницу, но нашел надлежащий ответ в другом месте:
http://www.rpm.org/max-rpm/s1-rpm-inside-macros.html
Это говорит, что можно передать-n %setup макросу, чтобы сказать rpmbuild название высокоуровневой папки в tarball
Эта статья была так близка к тому, что мне нужно, но не сигара. Функция переименования внутри Архива ::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;
}
}
По общему признанию, это предполагает, что первая запись в архиве является папкой. Но Вы получаете идею.