По имени
Вы можете сгенерировать список файлов в архиве и удалить их, хотя это раздражает, если использовать такие архиваторы, как unzip или 7z, у которых нет возможности создать простой список имен файлов. Даже при использовании tar предполагается, что в именах файлов нет новых строк.
tar tf foo.tar | while read -r file; do rm -- "$file" done
unzip -l foo.zip | awk '
p && /^ --/ {p=2}
p==1 {print substr($0, 29)}
/^ --/ {++p}
' | while …
unzip -l foo.zip | tail -n +4 | head -n -2 | while … # GNU coreutils only
7z l -slt foo.zip | sed -n 's/^Path = //p' | while … # works on tar.*, zip, 7z and more
Вместо удаления файлов вы можете переместить их по назначению.
tar tf foo.tar | while read -r file; do
if [ -d "$file" ]; then continue; fi
mkdir -p "/intended/destination/${file%/*}"
mv -- "$file" "/intended/destination/$file"
done
Использование FUSE
Вместо того, чтобы зависеть от внешних инструментов, вы можете (на большинстве устройств) использовать FUSE для управления архивами с помощью обычных команд файловой системы.
Вы можете использовать Fuse-zip, чтобы посмотреть в zip-архив, распаковать его cp
, просмотреть его содержимое find
и т. Д.
mkdir /tmp/foo.d
fuse-zip foo.zip /tmp/foo.d
## Remove the files that were extracted mistakenly (GNU/BSD find)
(cd /tmp/foo.d && find . \! -type d -print0) | xargs -0 rm
## Remove the files that were extracted mistakenly (zsh)
rm /tmp/foo.d/**(:"s~/tmp/foo.d/~~"^/)
## Extract the contents where you really want them
cp -Rp /tmp/foo.d /intended/destination
fusermount -u foo.d
rmdir foo.d
AVFS создает представление всей вашей иерархии каталогов, в котором все архивы имеют связанный каталог (с тем же именем, в конце которого стоит # tacked ), который, по-видимому, содержит содержимое архива.
mountavfs
## Remove the files that were extracted mistakenly (GNU/BSD find)
(cd ~/.avfs/"$PWD/foo.zip#" && find . \! -type d -print0) | xargs -0 rm
## Remove the files that were extracted mistakenly (zsh)
rm ~/.avfs/$PWD/foo.zip\#/**/*(:"s~$HOME/.avfs/$PWD/foo.zip#~~"^/)
## Extract the contents where you really want them
cp -Rp ~/.avfs/"$PWD/foo.zip#" /intended/destination
umountavfs
По дате
Предполагая, что в той же иерархии, что и ваше извлечение, не было других действий, вы можете указать извлеченные файлы по их последнему времени ctime . Если вы только что создали или переместили zip-файл, вы можете использовать его как обрезку; в противном случае используйте ls -lctr
для определения подходящего времени отключения. Если вы хотите убедиться, что молнии не сняты, нет никаких оснований для ручного одобрения: они find
вполне могут их исключить. Вот примеры команд, использующих zsh или find
; Следует отметить , что -cmin
и -cnewer
праймериз не в POSIX , но существуют на Linux (и других систем с GNU находке), * BSD и OSX.
find . \! -name '*.zip' -type f -cmin -5 -exec rm {} + # extracted <5 min ago
rm **/*~*.zip(.cm-6) # zsh, extracted ≤5 min ago
find . -type f -cnewer foo.zip -exec rm {} + # created or moved after foo.zip
В GNU find, FreeBSD и OSX еще один способ указать время отсечения - создать файл и использовать его touch
для установки в mtime времени отсечения.
touch -d … cutoff
find . -type f -newercm cutoff -delete
Вместо удаления файлов вы можете переместить их по назначению. Вот способ GNU / * BSD / OSX найти, создавая каталоги в месте назначения по мере необходимости.
find . \! -name . -cmin -5 -type f -exec sh -c '
for x; do
mkdir -p "$0/${x%/*}"
mv "$x" "$0/$x"
done
' /intended/destination {} +
Эквивалент Zsh (почти: он воспроизводит всю иерархию каталогов, а не только каталоги, которые будут содержать файлы):
autoload zmv
mkdir -p ./**/*(/cm-3:s"|.|/intended/destination|")
zmv -Q '(**/)(*)(.cm-3)' /intended/destination/'$1$2'
Предупреждение, я не проверял большинство команд в этом ответе. Всегда просматривайте список файлов перед удалением ( echo
сначала запустите , затем, rm
если все в порядке).