Ошибка Shell "tar: not found in archive" при использовании регулярного выражения

Когда я использую tar -xzf *.gz для извлечения всех файлов .gz в текущем каталоге, я получаю ошибку Not found in archive. Тем не менее, он отлично работает, если я извлекаю один за другим или использую for-loop, например

for file in `ls *.gz`; do tar -xzf $file; done

В чем причина этой ошибки?

Ответы

Ответ 1

Когда вы пишете:

tar -xf *.gz

команда tar видит (например):

tar -xf abc.tar.gz def.tar.gz ghi.tar.gz

Это интерпретируется как запрос на извлечение def.tar.gz и ghi.tar.gz из архива abc.tar.gz. Поскольку файлов там нет, вы получаете предупреждающее сообщение.

Другими словами, tar работает на одном файле tar (возможно, сжатом) за раз (в одном вызове). Он не работает с несколькими файлами tar.

Обратите внимание, что если abc.tar.gz содержит файл pqr/xyz/important.c, вы можете извлечь только один файл, указав:

tar -xf abc.tar.gz pqr/xyz/important.c

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

(И да, могут быть причины для файла tar a tar. Например, Gmail не позволяет отправлять tar файл или gzipped tar файл, который содержит исполняемый файл. Однако, если вы вставляете gzipped tar файл в несжатый tar файл, он не просматривает внутренний файл, чтобы найти исполняемый файл. Я использую это, когда мне нужно отправить tar файл с исполняемым файлом configure script.)

Ответ 2

Когда вы пишете

 tar -xzf *.gz

ваша оболочка расширяет ее до строки:

 tar -xzf 1.gz 2.gz 3.gz

(предполагая, что 1.gz, 2.gz и 3.gz находятся в вашем текущем каталоге).

tar думает, что вы хотите извлечь 2.gz и 3.gz из 1.gz; он не может найти эти файлы в архивах и вызывает сообщение об ошибке.

Для извлечения ваших файлов вам необходимо использовать цикл for команды xargs.

ls *.gz |xargs -n1 tar -xzf

Это означает: запустите me tar -xzf для каждого gz -file в текущем каталоге.

Ответ 3

Основная причина: tar принимает один аргумент имени файла. Когда вы вызываете tar *.tgz bash, он расширяет * ко всем именам файлов с помощью форматирования tgz и становится tar file1 file2 file3, который не принимается tar. Таким образом, либо вы используете цикл for, например for i in *.tgz; do tar -zxvf $i ;done, либо используете какую-либо другую команду, которая выполняет tar как побочный эффект, как показано в комментариях, ls или find . -maxdepth 1 -name \*tgz -exec tar -zxvf {} \; (ls вывод всегда опасен)